mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-03 08:49:03 +00:00
Modernize MakeROM build system + bug fixes (#120)
* Move files around to new directory structure * Rework libyaml into a stand-alone dep for makerom. * Rework libpolarssl to be standalone dependency for makerom. * Update includes. * Delete makefile * Add new makefile for makerom. * Update MakeROM github actions script. * Fix again. * Update MakeROM's makefile * Tweak makerom build script * Tweak MakeROM build script. * Fix typo * Update MakeROM makefiles. * Tweak CTRTool build script. * Tweak build script * Tweak CTRTool build script. * Tweak CTRTool build script * Add libmbedtls to makerom deps * Partially migrate makerom to libmbedtls * Break out libblz as an external dependency for makerom. * Tweak makerom build script. * Move dependencies to the top level. * Put everything back. * misc * Update makerom documentation. * Link to ctrtool/makerom readmes from the root readme. * Update root readme again. * Migrate makerom to modern mbedtls * Bump makerom version to 0.18.1 * Change signing errors to be warnings when they fail. * Add error verbosity to errors when generating CIA files. * Fix bug in RSA code. * misc. * Remove polarssl now migration to mbedtls complete. * Surface more makerom errors. * [makerom] Tolerate CCI signing errors as a warning. * Add missing return. * Import initial data key_x (prod/dev included) * [makerom] Fix initial data generation.
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
#include "lib.h"
|
||||
#include "ncch_build.h"
|
||||
#include "exheader_build.h"
|
||||
#include "accessdesc.h"
|
||||
|
||||
#include "desc/presets.h"
|
||||
#include "desc/dev_sigdata.h"
|
||||
|
||||
const size_t RSF_RSA_DATA_LEN = 344;
|
||||
const size_t RSF_DESC_DATA_LEN = 684;
|
||||
|
||||
|
||||
int accessdesc_SignWithKey(exheader_settings *exhdrset);
|
||||
int accessdesc_GetSignFromRsf(exheader_settings *exhdrset);
|
||||
int accessdesc_GetSignFromPreset(exheader_settings *exhdrset);
|
||||
const CtrSdkDesc* accessdesc_GetPresetData(keys_struct *keys);
|
||||
const CtrSdkDescSignData* accessdesc_GetPresetSignData(keys_struct *keys);
|
||||
const CtrSdkDepList* accessdesc_GetPresetDependencyList(keys_struct *keys);
|
||||
|
||||
int set_AccessDesc(exheader_settings *exhdrset)
|
||||
{
|
||||
if(exhdrset->useAccessDescPreset == true) // Use AccessDesc Template
|
||||
return accessdesc_GetSignFromPreset(exhdrset);
|
||||
else if(exhdrset->rsf->CommonHeaderKey.Found == true) // Keydata exists in RSF
|
||||
return accessdesc_GetSignFromRsf(exhdrset);
|
||||
return accessdesc_SignWithKey(exhdrset);
|
||||
}
|
||||
|
||||
int accessdesc_SignWithKey(exheader_settings *exhdrset)
|
||||
{
|
||||
/* Set RSA Keys */
|
||||
memcpy(exhdrset->keys->rsa.cxi.pvt, exhdrset->keys->rsa.cciCfa.pvt, 0x100);
|
||||
memcpy(exhdrset->keys->rsa.cxi.pub, exhdrset->keys->rsa.cciCfa.pub, 0x100);
|
||||
memcpy(&exhdrset->acexDesc->ncchRsaPubKey, exhdrset->keys->rsa.cxi.pub, 0x100);
|
||||
|
||||
/* Copy Data From ExHeader */
|
||||
memcpy(&exhdrset->acexDesc->arm11SystemLocalCapabilities, &exhdrset->exHdr->arm11SystemLocalCapabilities, sizeof(exhdr_ARM11SystemLocalCapabilities));
|
||||
memcpy(&exhdrset->acexDesc->arm11KernelCapabilities, &exhdrset->exHdr->arm11KernelCapabilities, sizeof(exhdr_ARM11KernelCapabilities));
|
||||
memcpy(&exhdrset->acexDesc->arm9AccessControlInfo, &exhdrset->exHdr->arm9AccessControlInfo, sizeof(exhdr_ARM9AccessControlInfo));
|
||||
|
||||
/* Adjust Data */
|
||||
exhdr_ARM11SystemLocalCapabilities *arm11 = &exhdrset->acexDesc->arm11SystemLocalCapabilities;
|
||||
|
||||
arm11->idealProcessor = 1 << arm11->idealProcessor;
|
||||
arm11->threadPriority /= 2;
|
||||
|
||||
/* Sign AccessDesc */
|
||||
if (Rsa2048Key_CanSign(&exhdrset->keys->rsa.acex) == false)
|
||||
{
|
||||
printf("[ACEXDESC WARNING] Failed to sign access descriptor (key was incomplete)\n");
|
||||
memset(exhdrset->acexDesc->signature, 0xFF, 0x100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rsa_ret = SignAccessDesc(exhdrset->acexDesc, exhdrset->keys);
|
||||
if (rsa_ret != 0)
|
||||
{
|
||||
printf("[ACEXDESC WARNING] Failed to sign access descriptor (mbedtls error = -0x%x)\n", -rsa_ret);
|
||||
memset(exhdrset->acexDesc->signature, 0xFF, 0x100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int accessdesc_GetSignFromRsf(exheader_settings *exhdrset)
|
||||
{
|
||||
/* Yaml Option Sanity Checks */
|
||||
if(!exhdrset->rsf->CommonHeaderKey.Found){
|
||||
fprintf(stderr,"[ACEXDESC ERROR] RSF Section \"CommonHeaderKey\" not found\n");
|
||||
return COMMON_HEADER_KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
if(!exhdrset->rsf->CommonHeaderKey.D){
|
||||
ErrorParamNotFound("CommonHeaderKey/D");
|
||||
return COMMON_HEADER_KEY_NOT_FOUND;
|
||||
}
|
||||
if(b64_strlen(exhdrset->rsf->CommonHeaderKey.D) != RSF_RSA_DATA_LEN){
|
||||
fprintf(stderr,"[ACEXDESC ERROR] \"CommonHeaderKey/D\" has invalid length (%d)\n", (int)b64_strlen(exhdrset->rsf->CommonHeaderKey.D));
|
||||
return COMMON_HEADER_KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
if(!exhdrset->rsf->CommonHeaderKey.Modulus){
|
||||
ErrorParamNotFound("CommonHeaderKey/Modulus");
|
||||
return COMMON_HEADER_KEY_NOT_FOUND;
|
||||
}
|
||||
if(b64_strlen(exhdrset->rsf->CommonHeaderKey.Modulus) != RSF_RSA_DATA_LEN){
|
||||
fprintf(stderr,"[ACEXDESC ERROR] \"CommonHeaderKey/Modulus\" has invalid length (%d)\n", (int)b64_strlen(exhdrset->rsf->CommonHeaderKey.Modulus));
|
||||
return COMMON_HEADER_KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
if(!exhdrset->rsf->CommonHeaderKey.AccCtlDescSign){
|
||||
ErrorParamNotFound("CommonHeaderKey/Signature");
|
||||
return COMMON_HEADER_KEY_NOT_FOUND;
|
||||
}
|
||||
if(b64_strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescSign) != RSF_RSA_DATA_LEN){
|
||||
fprintf(stderr,"[ACEXDESC ERROR] \"CommonHeaderKey/Signature\" has invalid length (%d)\n", (int)b64_strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescSign));
|
||||
return COMMON_HEADER_KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
if(!exhdrset->rsf->CommonHeaderKey.AccCtlDescBin){
|
||||
ErrorParamNotFound("CommonHeaderKey/Descriptor");
|
||||
return COMMON_HEADER_KEY_NOT_FOUND;
|
||||
}
|
||||
if(b64_strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescBin) != RSF_DESC_DATA_LEN){
|
||||
fprintf(stderr,"[ACEXDESC ERROR] \"CommonHeaderKey/Descriptor\" has invalid length (%d)\n", (int)b64_strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescBin));
|
||||
return COMMON_HEADER_KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Set RSA Keys */
|
||||
int result = 0;
|
||||
// NCCH Header pubk
|
||||
result = b64_decode(exhdrset->keys->rsa.cxi.pub,exhdrset->rsf->CommonHeaderKey.Modulus,0x100);
|
||||
if(result) return result;
|
||||
// NCCH Header privk
|
||||
result = b64_decode(exhdrset->keys->rsa.cxi.pvt,exhdrset->rsf->CommonHeaderKey.D,0x100);
|
||||
if(result) return result;
|
||||
|
||||
/* Set AccessDesc */
|
||||
// Signature
|
||||
result = b64_decode(exhdrset->acexDesc->signature,exhdrset->rsf->CommonHeaderKey.AccCtlDescSign,0x100);
|
||||
if(result) return result;
|
||||
// NCCH Header pubk
|
||||
memcpy(exhdrset->acexDesc->ncchRsaPubKey,exhdrset->keys->rsa.cxi.pub,0x100);
|
||||
// Access Control
|
||||
result = b64_decode((u8*)&exhdrset->acexDesc->arm11SystemLocalCapabilities,exhdrset->rsf->CommonHeaderKey.AccCtlDescBin,0x200);
|
||||
if(result) return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int accessdesc_GetSignFromPreset(exheader_settings *exhdrset)
|
||||
{
|
||||
const CtrSdkDesc *desc = accessdesc_GetPresetData(exhdrset->keys);
|
||||
const CtrSdkDescSignData *pre_sign = accessdesc_GetPresetSignData(exhdrset->keys);
|
||||
const CtrSdkDepList *dependency_list = accessdesc_GetPresetDependencyList(exhdrset->keys);
|
||||
|
||||
|
||||
// Error Checking
|
||||
if (!desc || !dependency_list) {
|
||||
fprintf(stderr, "[ACEXDESC ERROR] AccessDesc template is unavailable, please configure RSF file\n");
|
||||
return CANNOT_SIGN_ACCESSDESC;
|
||||
}
|
||||
|
||||
// Setting data in Exheader
|
||||
// Dependency List
|
||||
memcpy(exhdrset->exHdr->dependencyList, dependency_list->dependency, 0x180);
|
||||
|
||||
// Backing Up Non Preset Data
|
||||
u8 ProgramID[8];
|
||||
exhdr_StorageInfo StorageInfoBackup;
|
||||
exhdr_ARM9AccessControlInfo Arm9Desc;
|
||||
memcpy(ProgramID, exhdrset->exHdr->arm11SystemLocalCapabilities.programId, 8);
|
||||
memcpy(&StorageInfoBackup, &exhdrset->exHdr->arm11SystemLocalCapabilities.storageInfo, sizeof(exhdr_StorageInfo));
|
||||
memcpy(&Arm9Desc, &exhdrset->exHdr->arm9AccessControlInfo, sizeof(exhdr_ARM9AccessControlInfo));
|
||||
|
||||
// Setting Preset Data
|
||||
memcpy(&exhdrset->exHdr->arm11SystemLocalCapabilities, desc->exheader_desc, 0x200);
|
||||
|
||||
// Restoring Non Preset Data
|
||||
memcpy(exhdrset->exHdr->arm11SystemLocalCapabilities.programId, ProgramID, 8);
|
||||
memcpy(&exhdrset->exHdr->arm11SystemLocalCapabilities.storageInfo, &StorageInfoBackup, sizeof(exhdr_StorageInfo));
|
||||
memcpy(&exhdrset->exHdr->arm9AccessControlInfo, &Arm9Desc, sizeof(exhdr_ARM9AccessControlInfo));
|
||||
|
||||
|
||||
// Setting AccessDesc Area
|
||||
// If presign available set static data & ncch hdr sig info
|
||||
if (pre_sign)
|
||||
{
|
||||
memcpy(exhdrset->keys->rsa.cxi.pub, pre_sign->modulus, 0x100);
|
||||
memcpy(exhdrset->keys->rsa.cxi.pvt, pre_sign->priv_exponent, 0x100);
|
||||
memcpy(&exhdrset->acexDesc->signature, pre_sign->access_desc_signature, 0x100);
|
||||
memcpy(&exhdrset->acexDesc->ncchRsaPubKey, pre_sign->modulus, 0x100);
|
||||
memcpy(&exhdrset->acexDesc->arm11SystemLocalCapabilities, desc->signed_desc, 0x200);
|
||||
}
|
||||
// otherwise sign properly
|
||||
else
|
||||
{
|
||||
return accessdesc_SignWithKey(exhdrset);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const CtrSdkDesc* accessdesc_GetPresetData(keys_struct *keys)
|
||||
{
|
||||
for (int i = 0; i < sizeof(kDescPresets) / sizeof(CtrSdkDesc); i++) {
|
||||
if (kDescPresets[i].type == keys->accessDescSign.presetType && kDescPresets[i].fw_minor == keys->accessDescSign.targetFirmware) {
|
||||
return &kDescPresets[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const CtrSdkDescSignData* accessdesc_GetPresetSignData(keys_struct *keys)
|
||||
{
|
||||
if (keys->keyset != pki_DEVELOPMENT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(kDevDescSignData) / sizeof(CtrSdkDescSignData); i++) {
|
||||
if (kDevDescSignData[i].type == keys->accessDescSign.presetType && kDevDescSignData[i].fw_minor == keys->accessDescSign.targetFirmware) {
|
||||
return &kDevDescSignData[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const CtrSdkDepList* accessdesc_GetPresetDependencyList(keys_struct *keys)
|
||||
{
|
||||
for (int i = 0; i < sizeof(kExheaderDependencyLists) / sizeof(CtrSdkDepList); i++) {
|
||||
if (kExheaderDependencyLists[i].fw_minor == keys->accessDescSign.targetFirmware) {
|
||||
return &kExheaderDependencyLists[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
int set_AccessDesc(exheader_settings *exhdrset);
|
||||
@@ -0,0 +1,119 @@
|
||||
#include "aes_keygen.h"
|
||||
|
||||
// 128bit wrap-around math
|
||||
int32_t wrap_index(int32_t i)
|
||||
{
|
||||
return i < 0 ? ((i % 16) + 16) % 16 : (i > 15 ? i % 16 : i);
|
||||
}
|
||||
|
||||
void n128_rrot(const uint8_t *in, uint32_t rot, uint8_t *out)
|
||||
{
|
||||
uint32_t bit_shift, byte_shift;
|
||||
|
||||
rot = rot % 128;
|
||||
byte_shift = rot / 8;
|
||||
bit_shift = rot % 8;
|
||||
|
||||
for (int32_t i = 0; i < 16; i++) {
|
||||
out[i] = (in[wrap_index(i - byte_shift)] >> bit_shift) | (in[wrap_index(i - byte_shift - 1)] << (8 - bit_shift));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void n128_lrot(const uint8_t *in, uint32_t rot, uint8_t *out)
|
||||
{
|
||||
uint32_t bit_shift, byte_shift;
|
||||
|
||||
rot = rot % 128;
|
||||
byte_shift = rot / 8;
|
||||
bit_shift = rot % 8;
|
||||
|
||||
for (int32_t i = 0; i < 16; i++) {
|
||||
out[i] = (in[wrap_index(i + byte_shift)] << bit_shift) | (in[wrap_index(i + byte_shift + 1)] >> (8 - bit_shift));
|
||||
}
|
||||
}
|
||||
|
||||
/* out = a + b
|
||||
*/
|
||||
void n128_add(const uint8_t *a, const uint8_t *b, uint8_t *out)
|
||||
{
|
||||
uint8_t carry = 0;
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
sum = a[i] + b[i] + carry;
|
||||
carry = sum >> 8;
|
||||
out[i] = sum & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/* out = a - b
|
||||
*/
|
||||
void n128_sub(const uint8_t *a, const uint8_t *b, uint8_t *out)
|
||||
{
|
||||
uint8_t carry = 0;
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
sum = a[i] - (b[i] + carry);
|
||||
|
||||
// check to see if anything was borrowed from next byte
|
||||
if (a[i] < (b[i] + carry)) {
|
||||
sum += 0x100;
|
||||
carry = 1;
|
||||
}
|
||||
else {
|
||||
carry = 0;
|
||||
}
|
||||
|
||||
// set value
|
||||
out[i] = sum & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void n128_xor(const uint8_t *a, const uint8_t *b, uint8_t *out)
|
||||
{
|
||||
for (int i = 0; i < 16; i++) {
|
||||
out[i] = a[i] ^ b[i];
|
||||
}
|
||||
}
|
||||
|
||||
// keygen algorithm
|
||||
/*
|
||||
void n_aes_keygen(const uint8_t *x, uint8_t x_shift, const uint8_t *y, uint8_t y_shift, const uint8_t *keygen_constant, uint8_t *key)
|
||||
{
|
||||
// overall algo:
|
||||
// key = ((x >>> x_shift) ^ (y >>> y_shift)) + keygen_constant
|
||||
uint8_t x_rot[16], y_rot[16], key_xy[16];
|
||||
|
||||
// Rotate x and y
|
||||
n128_rrot(x, x_shift, x_rot);
|
||||
n128_rrot(y, y_shift, y_rot);
|
||||
|
||||
// XOR rotated x and y
|
||||
n128_xor(x_rot, y_rot, key_xy);
|
||||
|
||||
// Add secret
|
||||
n128_add(key_xy, keygen_constant, key);
|
||||
}
|
||||
*/
|
||||
|
||||
void ctr_aes_keygen(const uint8_t *x, const uint8_t *y, uint8_t *key)
|
||||
{
|
||||
static const uint8_t KEYGEN_CONST[16] = { 0x1F, 0xF9, 0xE9, 0xAA, 0xC5, 0xFE, 0x04, 0x08, 0x02, 0x45, 0x91, 0xDC, 0x5D, 0x52, 0x76, 0x8A };
|
||||
|
||||
// overall algo:
|
||||
// key = (((x <<< 2) ^ y) + KEYGEN_CONST) >>> 41
|
||||
uint8_t x_rot[16], key_xy[16], key_xyc[16];
|
||||
|
||||
// x_rot = x <<< 2
|
||||
n128_lrot(x, 2, x_rot);
|
||||
|
||||
// key_xy = x_rot ^ y
|
||||
n128_xor(x_rot, y, key_xy);
|
||||
|
||||
// key_xyc = key_xy + KEYGEN_CONST
|
||||
n128_add(key_xy, KEYGEN_CONST, key_xyc);
|
||||
|
||||
n128_rrot(key_xyc, 41, key);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
AES Key generator for the Nintendo 3DS (CTR) Consoles
|
||||
*/
|
||||
|
||||
void ctr_aes_keygen(const uint8_t *x, const uint8_t *y, uint8_t *key);
|
||||
@@ -0,0 +1,286 @@
|
||||
#include "lib.h"
|
||||
|
||||
#include <mbedtls/ccm.h>
|
||||
#include "aes_keygen.h"
|
||||
|
||||
#include "ncch_read.h"
|
||||
#include "ncsd_build.h"
|
||||
#include "cardinfo.h"
|
||||
|
||||
void InitCardInfoHdr(cardinfo_hdr **cihdr, devcardinfo_hdr **dcihdr, cci_settings *set);
|
||||
int SetWriteableAddress(cardinfo_hdr *hdr, cci_settings *set);
|
||||
int SetCardInfoBitmask(cardinfo_hdr *hdr, cci_settings *set);
|
||||
int SetCardInfoNotes(cardinfo_hdr *hdr, cci_settings *set);
|
||||
void SetNcchHeader(cardinfo_hdr *hdr, cci_settings *set);
|
||||
void SetCardSeedData(cardinfo_hdr *hdr, devcardinfo_hdr *devhdr, cci_settings *set);
|
||||
|
||||
|
||||
int GenCardInfoHdr(cci_settings *set)
|
||||
{
|
||||
cardinfo_hdr *cihdr;
|
||||
devcardinfo_hdr *dcihdr;
|
||||
|
||||
InitCardInfoHdr(&cihdr,&dcihdr,set);
|
||||
|
||||
if(SetWriteableAddress(cihdr,set))
|
||||
return GEN_HDR_FAIL;
|
||||
if(SetCardInfoBitmask(cihdr,set))
|
||||
return GEN_HDR_FAIL;
|
||||
if(SetCardInfoNotes(cihdr,set))
|
||||
return GEN_HDR_FAIL;
|
||||
SetNcchHeader(cihdr,set);
|
||||
SetCardSeedData(cihdr,dcihdr,set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitCardInfoHdr(cardinfo_hdr **cihdr, devcardinfo_hdr **dcihdr, cci_settings *set)
|
||||
{
|
||||
set->headers.cardinfohdr.size = sizeof(cardinfo_hdr) + sizeof(devcardinfo_hdr);
|
||||
set->headers.cardinfohdr.buffer = calloc(1,set->headers.cardinfohdr.size);
|
||||
|
||||
*cihdr = (cardinfo_hdr*)set->headers.cardinfohdr.buffer;
|
||||
*dcihdr = (devcardinfo_hdr*)(set->headers.cardinfohdr.buffer+sizeof(cardinfo_hdr));
|
||||
|
||||
clrmem(set->headers.cardinfohdr.buffer, set->headers.cardinfohdr.size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
u64 GetCciUnusedSize(u64 mediaSize, u8 cardType)
|
||||
{
|
||||
if(cardType == mediatype_CARD1){
|
||||
switch(mediaSize){
|
||||
case (u64)MB*128: return (u64)2621440;
|
||||
case (u64)MB*256: return (u64)5242880;
|
||||
case (u64)MB*512: return (u64)10485760;
|
||||
case (u64)GB*1: return (u64)73924608;
|
||||
case (u64)GB*2: return (u64)147324928;
|
||||
case (u64)GB*4: return (u64)294649856;
|
||||
case (u64)GB*8: return (u64)587202560;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
else if(cardType == mediatype_CARD2){
|
||||
switch(mediaSize){
|
||||
case (u64)MB*512: return (u64)37224448;
|
||||
case (u64)GB*1: return (u64)73924608;
|
||||
case (u64)GB*2: return (u64)147324928;
|
||||
case (u64)GB*4: return (u64)294649856;
|
||||
case (u64)GB*8: return (u64)587202560;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetWriteableAddress(cardinfo_hdr *hdr, cci_settings *set)
|
||||
{
|
||||
if(set->romInfo.mediaType != mediatype_CARD2){ // Can only be set for Card2 Media
|
||||
u32_to_u8(hdr->writableAddress,(u32)-1,LE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *str = set->rsf->CardInfo.WritableAddress;
|
||||
set->romInfo.card2SaveOffset = -1;
|
||||
|
||||
if(str){
|
||||
if(strncmp(str,"0x",2) != 0){
|
||||
fprintf(stderr,"[CCI ERROR] WritableAddress requires a Hexadecimal value\n");
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
set->romInfo.card2SaveOffset = strtoull(str,NULL,16);
|
||||
}
|
||||
else{
|
||||
if ((set->romInfo.mediaSize / 2) < set->romInfo.saveSize || set->romInfo.saveSize > (u64)(2047*MB)){
|
||||
u64 saveDataSize = set->romInfo.saveSize / KB;
|
||||
fprintf(stderr,"[CCI ERROR] Too large SavedataSize %"PRIu64"K\n",saveDataSize);
|
||||
return SAVE_DATA_TOO_LARGE;
|
||||
}
|
||||
if(set->options.closeAlignWR)
|
||||
set->romInfo.card2SaveOffset = align(set->romInfo.usedSize, set->romInfo.blockSize); // invalid for "real" chips
|
||||
else{
|
||||
u64 unusedSize = GetCciUnusedSize(set->romInfo.mediaSize,set->romInfo.mediaType); // Some value related to the physical implementation of gamecards
|
||||
if(unusedSize > 0)
|
||||
set->romInfo.card2SaveOffset = set->romInfo.mediaSize - unusedSize - set->romInfo.saveSize; // Nintendo's method for calculating writable region offset
|
||||
else{
|
||||
fprintf(stderr,"[CCI WARNING] Nintendo does not support CARD2 for the current MediaSize, aligning save offset after last NCCH\n");
|
||||
set->romInfo.card2SaveOffset = align(set->romInfo.usedSize, set->romInfo.blockSize); // invalid for "real" chips
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32_to_u8(hdr->writableAddress,(u32)(set->romInfo.card2SaveOffset/set->romInfo.blockSize),LE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetCardInfoBitmask(cardinfo_hdr *hdr, cci_settings *set)
|
||||
{
|
||||
u32 bitmask = 0;
|
||||
|
||||
char *str = set->rsf->CardInfo.CardType;
|
||||
if(!str)
|
||||
bitmask |= 0 << 5;
|
||||
else{
|
||||
if(strcasecmp(str,"s1") == 0)
|
||||
bitmask |= 0 << 5;
|
||||
else if(strcasecmp(str,"s2") == 0)
|
||||
bitmask |= 1 << 5;
|
||||
else {
|
||||
fprintf(stderr,"[CCI ERROR] Invalid CardType: %s\n",str);
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
}
|
||||
|
||||
str = set->rsf->CardInfo.CryptoType;
|
||||
if(!str) {
|
||||
if(set->options.useExternalSdkCardInfo)
|
||||
bitmask |= (3 << 6);
|
||||
else
|
||||
bitmask |= 0;
|
||||
}
|
||||
else{
|
||||
int val = strtol(str,NULL,10);
|
||||
if(val < 0 || val > 3) {
|
||||
fprintf(stderr,"[CCI ERROR] Invalid CryptoType: %s\n",str);
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
if(val != 3 && set->keys->keyset == pki_DEVELOPMENT) {
|
||||
fprintf(stderr,"[CCI WARNING] Card crypto type = '%d', this is not supported for development target.\n",val);
|
||||
}
|
||||
if(val == 3 && set->keys->keyset == pki_PRODUCTION) {
|
||||
fprintf(stderr,"[CCI WARNING] Card crypto type = '%d', this is not supported for production target.\n",val);
|
||||
}
|
||||
|
||||
bitmask |= val << 6;
|
||||
}
|
||||
|
||||
u32_to_u8(hdr->cardInfoBitmask,bitmask,BE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetCardInfoNotes(cardinfo_hdr *hdr, cci_settings *set)
|
||||
{
|
||||
u64_to_u8(hdr->notes.mediaSizeUsed,set->romInfo.usedSize,LE);
|
||||
u32_to_u8(hdr->notes.unknown,0,LE);
|
||||
|
||||
if(set->options.tmdHdr){
|
||||
u64_to_u8(hdr->notes.cverTitleId,GetTmdTitleId(set->options.tmdHdr),LE);
|
||||
u16_to_u8(hdr->notes.cverTitleId,GetTmdVersion(set->options.tmdHdr),LE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetNcchHeader(cardinfo_hdr *hdr, cci_settings *set)
|
||||
{
|
||||
u8 *ncch;
|
||||
ncch_hdr *ncchHdr;
|
||||
|
||||
ncch = set->content.data + set->content.dOffset[0];
|
||||
ncchHdr = (ncch_hdr*)ncch;
|
||||
|
||||
memcpy(hdr->ncch0Hdr,GetNcchHdrData(ncchHdr),GetNcchHdrDataLen(ncchHdr));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void SetCardSeedData(cardinfo_hdr *hdr, devcardinfo_hdr *devhdr, cci_settings *set)
|
||||
{
|
||||
u8 *ncch;
|
||||
ncch_hdr *ncchHdr;
|
||||
|
||||
ncch = set->content.data + set->content.dOffset[0];
|
||||
ncchHdr = (ncch_hdr*)ncch;
|
||||
|
||||
/*
|
||||
if (set->options.useExternalSdkCardInfo) {
|
||||
// initial data
|
||||
clrmem(hdr->cardSeedKeyY, 0x10);
|
||||
memcpy(hdr->cardSeedKeyY, ncchHdr->titleId, 8);
|
||||
clrmem(hdr->encCardSeed, 0x10);
|
||||
memcpy(hdr->cardSeedMac, stock_card_seed_mac, 0x10);
|
||||
clrmem(hdr->cardSeedNonce, 0xC);
|
||||
|
||||
// dev card info
|
||||
memcpy(devhdr->titleKey, stock_title_key, 0x10);
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// select title_key
|
||||
u8 title_key[0x10] = {0};
|
||||
if (set->options.useExternalSdkCardInfo)
|
||||
{
|
||||
memcpy(title_key, stock_title_key, 0x10);
|
||||
}
|
||||
else
|
||||
{
|
||||
rndset(title_key, 0x10);
|
||||
}
|
||||
|
||||
// generate initial data
|
||||
{
|
||||
// set the keyY
|
||||
clrmem(hdr->cardSeedKeyY, 0x10);
|
||||
memcpy(hdr->cardSeedKeyY, ncchHdr->titleId, 8);
|
||||
|
||||
// use crypto type to determine initial data key
|
||||
uint32_t crypto_type = (u8_to_u32(hdr->cardInfoBitmask, BE) >> 6) & 3;
|
||||
u8 initial_data_key[0x10] = {0};
|
||||
if (crypto_type == 3)
|
||||
{
|
||||
clrmem(initial_data_key, 0x10);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctr_aes_keygen(set->keys->aes.initialDataKeyX, hdr->cardSeedKeyY, initial_data_key);
|
||||
}
|
||||
|
||||
// determine nonce
|
||||
if (set->options.useExternalSdkCardInfo)
|
||||
{
|
||||
clrmem(hdr->cardSeedNonce, 0xC);
|
||||
}
|
||||
else
|
||||
{
|
||||
rndset(hdr->cardSeedNonce, 0xC);
|
||||
}
|
||||
|
||||
// encrypt title key (& generate MAC)
|
||||
mbedtls_ccm_context ccm_ctx;
|
||||
mbedtls_ccm_init(&ccm_ctx);
|
||||
mbedtls_ccm_setkey(&ccm_ctx, MBEDTLS_CIPHER_ID_AES, initial_data_key, 128);
|
||||
|
||||
int ccm_ret = mbedtls_ccm_encrypt_and_tag(&ccm_ctx, sizeof(title_key), hdr->cardSeedNonce, sizeof(hdr->cardSeedNonce), NULL, 0, title_key, hdr->encCardSeed, hdr->cardSeedMac, sizeof(hdr->cardSeedMac));
|
||||
if (ccm_ret != 0)
|
||||
{
|
||||
printf("[CARDINFO WARNING] Failed to encrypt initial data (mbedtls error: -0x%04X)\n", -ccm_ret);
|
||||
}
|
||||
|
||||
mbedtls_ccm_free(&ccm_ctx);
|
||||
}
|
||||
|
||||
// generate dev card info header
|
||||
{
|
||||
memcpy(devhdr->titleKey, title_key, 0x10);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void SetDevCardInfo(devcardinfo_hdr *hdr, cci_settings *set)
|
||||
{
|
||||
clrmem(hdr,sizeof(devcardinfo_hdr));
|
||||
if(set->options.useExternalSdkCardInfo)
|
||||
memcpy(hdr->titleKey,(u8*)stock_title_key,0x10);
|
||||
else
|
||||
rndset(hdr->titleKey,0x10);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 reserved0[0xf8];
|
||||
u8 mediaSizeUsed[8];
|
||||
u8 reserved1[0x8];
|
||||
u8 unknown[0x4];
|
||||
u8 reserved2[0xc];
|
||||
u8 cverTitleId[8];
|
||||
u8 cverTitleVersion[2];
|
||||
u8 reserved3[0xcd6];
|
||||
} cardinfo_notes; // reserved[0xDF8];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 writableAddress[4];
|
||||
u8 cardInfoBitmask[4];
|
||||
cardinfo_notes notes;
|
||||
u8 cardSeedKeyY[0x10];
|
||||
u8 encCardSeed[0x10];
|
||||
u8 cardSeedMac[0x10];
|
||||
u8 cardSeedNonce[0xc];
|
||||
u8 reserved1[0xc4];
|
||||
u8 ncch0Hdr[0x100];
|
||||
} cardinfo_hdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 cardDeviceReserved1[0x200];
|
||||
u8 titleKey[0x10];
|
||||
u8 cardDeviceReserved2[0xf0];
|
||||
} devcardinfo_hdr;
|
||||
|
||||
static const u8 stock_card_seed_mac[0x30] =
|
||||
{
|
||||
0xAD, 0x88, 0xAC, 0x41, 0xA2, 0xB1, 0x5E, 0x8F, 0x66, 0x9C, 0x97, 0xE5, 0xE1, 0x5E, 0xA3, 0xEB
|
||||
};
|
||||
|
||||
static const u8 stock_title_key[0x10] =
|
||||
{
|
||||
0x6E, 0xC7, 0x5F, 0xB2, 0xE2, 0xB4,
|
||||
0x87, 0x46, 0x1E, 0xDD, 0xCB, 0xB8,
|
||||
0x97, 0x11, 0x92, 0xBA
|
||||
};
|
||||
|
||||
int GenCardInfoHdr(cci_settings *set);
|
||||
@@ -0,0 +1,113 @@
|
||||
#include "lib.h"
|
||||
#include "certs.h"
|
||||
|
||||
// Cert Sizes
|
||||
void GetCertSigSectionSizes(u32 *sign_size, u32 *sign_padlen, u8 *cert)
|
||||
{
|
||||
u32 sig = u8_to_u32(cert,BE);
|
||||
switch(sig){
|
||||
case RSA_4096_SHA1 :
|
||||
*sign_size = 0x200;
|
||||
*sign_padlen = 0x3C;
|
||||
break;
|
||||
case RSA_2048_SHA1 :
|
||||
*sign_size = 0x100;
|
||||
*sign_padlen = 0x3C;
|
||||
break;
|
||||
case ECC_SHA1 :
|
||||
*sign_size = 0x3C;
|
||||
*sign_padlen = 0x40;
|
||||
break;
|
||||
case RSA_4096_SHA256 :
|
||||
*sign_size = 0x200;
|
||||
*sign_padlen = 0x3C;
|
||||
break;
|
||||
case RSA_2048_SHA256 :
|
||||
*sign_size = 0x100;
|
||||
*sign_padlen = 0x3C;
|
||||
break;
|
||||
case ECC_SHA256 :
|
||||
*sign_size = 0x3C;
|
||||
*sign_padlen = 0x40;
|
||||
break;
|
||||
default :
|
||||
*sign_size = 0;
|
||||
*sign_padlen = 0;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
u32 GetCertSize(u8 *cert)
|
||||
{
|
||||
u32 sign_size = 0;
|
||||
u32 sign_padlen = 0;
|
||||
GetCertSigSectionSizes(&sign_size,&sign_padlen,cert);
|
||||
if(!sign_size || !sign_padlen)
|
||||
return 0;
|
||||
|
||||
return sizeof(u32) + sign_size + sign_padlen + sizeof(cert_hdr) + GetCertPubkSectionSize(GetCertPubkType(cert));
|
||||
}
|
||||
|
||||
|
||||
cert_hdr* GetCertHdr(u8 *cert)
|
||||
{
|
||||
u32 sign_size = 0;
|
||||
u32 sign_padlen = 0;
|
||||
GetCertSigSectionSizes(&sign_size,&sign_padlen,cert);
|
||||
if(!sign_size || !sign_padlen) return NULL;
|
||||
|
||||
return (cert_hdr*)(cert+4+sign_size+sign_padlen);
|
||||
}
|
||||
|
||||
u32 GetCertPubkSectionSize(pubk_types type)
|
||||
{
|
||||
switch(type){
|
||||
case RSA_4096_PUBK : return sizeof(rsa_4096_pubk_struct);
|
||||
case RSA_2048_PUBK : return sizeof(rsa_2048_pubk_struct);
|
||||
case ECC_PUBK : return sizeof(ecc_pubk_struct);
|
||||
default : return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Issuer/Name Functions
|
||||
u8 *GetCertIssuer(u8 *cert)
|
||||
{
|
||||
cert_hdr *hdr = GetCertHdr(cert);
|
||||
return hdr->issuer;
|
||||
}
|
||||
u8 *GetCertName(u8 *cert)
|
||||
{
|
||||
cert_hdr *hdr = GetCertHdr(cert);
|
||||
return hdr->name;
|
||||
}
|
||||
|
||||
void GenCertChildIssuer(u8 *dest, u8 *cert)
|
||||
{
|
||||
snprintf((char*)dest,0x40,"%s-%s",GetCertIssuer(cert),GetCertName(cert));
|
||||
}
|
||||
|
||||
// Pubk
|
||||
pubk_types GetCertPubkType(u8 *cert)
|
||||
{
|
||||
cert_hdr *hdr = GetCertHdr(cert);
|
||||
|
||||
return (pubk_types)u8_to_u32(hdr->keyType,BE);
|
||||
}
|
||||
u8 *GetCertPubk(u8 *cert)
|
||||
{
|
||||
if(!GetCertHdr(cert))
|
||||
return NULL;
|
||||
return ((u8*)GetCertHdr(cert)) + sizeof(cert_hdr);
|
||||
}
|
||||
|
||||
bool VerifyCert(u8 *cert, u8 *pubk)
|
||||
{
|
||||
if(!GetCertHdr(cert))
|
||||
return false;
|
||||
u8 *signature = (cert+sizeof(u32));
|
||||
u8 *data = (u8*)GetCertHdr(cert);
|
||||
u32 datasize = sizeof(cert_hdr) + GetCertPubkSectionSize(GetCertPubkType(cert));
|
||||
|
||||
return RsaSignVerify(data,datasize,signature,pubk,NULL,u8_to_u32(cert,BE),CTR_RSA_VERIFY);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 issuer[0x40];
|
||||
u8 keyType[4];
|
||||
u8 name[0x40];
|
||||
u8 id[4];
|
||||
} cert_hdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 modulus[0x200];
|
||||
u8 pubExponent[4];
|
||||
u8 padding[0x34];
|
||||
} rsa_4096_pubk_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 modulus[0x100];
|
||||
u8 pubExponent[4];
|
||||
u8 padding[0x34];
|
||||
} rsa_2048_pubk_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 pubK[0x3C];
|
||||
u8 padding[0x3C];
|
||||
} ecc_pubk_struct;
|
||||
|
||||
// Cert Sizes
|
||||
u32 GetCertSize(u8 *cert);
|
||||
u32 GetCertPubkSectionSize(pubk_types type);
|
||||
|
||||
// Issuer/Name Functions
|
||||
u8 *GetCertIssuer(u8 *cert);
|
||||
u8 *GetCertName(u8 *cert);
|
||||
void GenCertChildIssuer(u8 *dest, u8 *cert);
|
||||
|
||||
// Pubk
|
||||
pubk_types GetCertPubkType(u8 *cert);
|
||||
u8 *GetCertPubk(u8 *cert);
|
||||
|
||||
bool VerifyCert(u8 *cert, u8 *pubk);
|
||||
@@ -0,0 +1,807 @@
|
||||
#include "lib.h"
|
||||
|
||||
#include "srl.h"
|
||||
#include "ncsd_read.h"
|
||||
#include "ncch_read.h"
|
||||
#include "exheader_read.h"
|
||||
#include "exefs_read.h"
|
||||
|
||||
#include "cia_build.h"
|
||||
#include "cia_read.h"
|
||||
#include "tik_build.h"
|
||||
#include "tmd_build.h"
|
||||
#include "titleid.h"
|
||||
#include "certs.h"
|
||||
|
||||
const int CIA_ALIGN_SIZE = 0x40;
|
||||
const int CIA_CONTENT_ALIGN = 0x10;
|
||||
|
||||
// Private Prototypes
|
||||
void FreeCiaSettings(cia_settings *set);
|
||||
int GetCiaSettings(cia_settings *ciaset, user_settings *usrset);
|
||||
|
||||
int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset);
|
||||
int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset);
|
||||
int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *key);
|
||||
int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *key);
|
||||
int GetContentFilePtrs(cia_settings *ciaset, user_settings *usrset);
|
||||
int ImportNcchContent(cia_settings *ciaset);
|
||||
int GetSettingsFromSrl(cia_settings *ciaset);
|
||||
int GetSettingsFromCci(cia_settings *ciaset);
|
||||
|
||||
u16 SetupVersion(u16 major, u16 minor, u16 micro);
|
||||
|
||||
void GetContentHashes(cia_settings *ciaset);
|
||||
void EncryptContent(cia_settings *ciaset);
|
||||
|
||||
int BuildCiaCertChain(cia_settings *ciaset);
|
||||
int BuildCiaHdr(cia_settings *ciaset);
|
||||
|
||||
int WriteCiaToFile(cia_settings *ciaset);
|
||||
|
||||
|
||||
int build_CIA(user_settings *usrset)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
// Init Settings
|
||||
cia_settings *ciaset = calloc(1,sizeof(cia_settings));
|
||||
if(!ciaset) {
|
||||
fprintf(stderr,"[CIA ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
|
||||
// Get Settings
|
||||
result = GetCiaSettings(ciaset,usrset);
|
||||
if(result) {
|
||||
fprintf(stderr,"[CIA ERROR] Failed to initialize context.\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
// Create Output File
|
||||
ciaset->out = fopen(usrset->common.outFileName,"wb");
|
||||
if(!ciaset->out){
|
||||
fprintf(stderr,"[CIA ERROR] Failed to create \"%s\"\n",usrset->common.outFileName);
|
||||
result = FAILED_TO_CREATE_OUTFILE;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
// Create CIA Sections
|
||||
|
||||
/* Certificate Chain */
|
||||
result = BuildCiaCertChain(ciaset);
|
||||
if(result) {
|
||||
fprintf(stderr,"[CIA ERROR] Failed to build Certificate Chain\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Ticket */
|
||||
result = BuildTicket(ciaset);
|
||||
if(result) {
|
||||
fprintf(stderr,"[CIA ERROR] Failed to build Ticket\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Title Metadata */
|
||||
result = BuildTMD(ciaset);
|
||||
if(result) {
|
||||
fprintf(stderr,"[CIA ERROR] Failed to build Title Metadata\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* CIA Header */
|
||||
result = BuildCiaHdr(ciaset);
|
||||
if(result) {
|
||||
fprintf(stderr,"[CIA ERROR] Failed to build CIA Header\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Write To File */
|
||||
result = WriteCiaToFile(ciaset);
|
||||
if(result) {
|
||||
fprintf(stderr,"[CIA ERROR] Failed to write CIA to file\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if(result != FAILED_TO_CREATE_OUTFILE && ciaset->out)
|
||||
fclose(ciaset->out);
|
||||
|
||||
FreeCiaSettings(ciaset);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FreeCiaSettings(cia_settings *set)
|
||||
{
|
||||
if(set->content.filePtrs){
|
||||
for(u32 i = 1; i < set->content.count; i++){
|
||||
fclose(set->content.filePtrs[i]);
|
||||
}
|
||||
free(set->content.filePtrs);
|
||||
}
|
||||
free(set->ciaSections.certChain.buffer);
|
||||
free(set->ciaSections.tik.buffer);
|
||||
free(set->ciaSections.tmd.buffer);
|
||||
free(set->ciaSections.meta.buffer);
|
||||
free(set->ciaSections.content.buffer);
|
||||
|
||||
memset(set,0,sizeof(cia_settings));
|
||||
|
||||
free(set);
|
||||
}
|
||||
|
||||
int GetCiaSettings(cia_settings *ciaset, user_settings *usrset)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
// Transfering data from usrset
|
||||
result = GetSettingsFromUsrset(ciaset,usrset);
|
||||
|
||||
if(usrset->common.workingFileType == infile_ncch){
|
||||
if((result = GetSettingsFromNcch0(ciaset,0)) != 0)
|
||||
return result;
|
||||
if((result = GetContentFilePtrs(ciaset,usrset)) != 0)
|
||||
return result;
|
||||
if((result = ImportNcchContent(ciaset)) != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
else if(usrset->common.workingFileType == infile_srl){
|
||||
if((result = GetSettingsFromSrl(ciaset)) != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
else if(usrset->common.workingFileType == infile_ncsd){
|
||||
if((result = GetSettingsFromCci(ciaset)) != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
GetContentHashes(ciaset);
|
||||
|
||||
if(ciaset->content.encryptCia)
|
||||
EncryptContent(ciaset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset)
|
||||
{
|
||||
// General Stuff
|
||||
ciaset->keys = &usrset->common.keys;
|
||||
ciaset->rsf = &usrset->common.rsfSet;
|
||||
ciaset->ciaSections.content.buffer = usrset->common.workingFile.buffer;
|
||||
ciaset->ciaSections.content.size = usrset->common.workingFile.size;
|
||||
usrset->common.workingFile.buffer = NULL;
|
||||
usrset->common.workingFile.size = 0;
|
||||
ciaset->content.includeUpdateNcch = usrset->cia.includeUpdateNcch;
|
||||
ciaset->verbose = usrset->common.verbose;
|
||||
|
||||
ciaset->tmd.titleType = TYPE_CTR;
|
||||
ciaset->content.encryptCia = usrset->common.rsfSet.Option.EnableCrypt || usrset->cia.titleKey != NULL;
|
||||
ciaset->content.IsDlc = usrset->cia.DlcContent;
|
||||
if(ciaset->keys->aes.commonKey[ciaset->keys->aes.currentCommonKey] == NULL && ciaset->content.encryptCia){
|
||||
fprintf(stderr,"[CIA WARNING] Common Key could not be loaded, CIA will not be encrypted\n");
|
||||
ciaset->content.encryptCia = false;
|
||||
}
|
||||
|
||||
ciaset->cert.caCrlVersion = 0;
|
||||
ciaset->cert.signerCrlVersion = 0;
|
||||
|
||||
ciaset->common.useCxiRemasterVersion = !usrset->cia.useFullTitleVer;
|
||||
for(int i = 0; i < 3; i++){
|
||||
ciaset->common.titleVersion[i] = usrset->cia.titleVersion[i];
|
||||
}
|
||||
|
||||
// Ticket Data
|
||||
ciaset->tik.ticketId = 0x0004000000000000 | (u64GetRand() & 0x0000FFFFFFFFFFFF);
|
||||
ciaset->tik.deviceId = usrset->cia.deviceId;
|
||||
ciaset->tik.eshopAccId = usrset->cia.eshopAccId;
|
||||
ciaset->tik.licenceType = lic_Permanent;
|
||||
ciaset->tik.audit = 0;
|
||||
|
||||
if(usrset->cia.randomTitleKey)
|
||||
rndset(ciaset->common.titleKey,AES_128_KEY_SIZE);
|
||||
else if(usrset->cia.titleKey){
|
||||
for (size_t count = 0; count < sizeof(ciaset->common.titleKey)/sizeof(ciaset->common.titleKey[0]); count++) {
|
||||
sscanf(usrset->cia.titleKey, "%2hhx", &ciaset->common.titleKey[count]);
|
||||
usrset->cia.titleKey += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
clrmem(ciaset->common.titleKey,AES_128_KEY_SIZE);
|
||||
|
||||
if(ciaset->verbose)
|
||||
memdump(stdout,"[CIA] CIA title key: ",ciaset->common.titleKey,AES_128_KEY_SIZE);
|
||||
|
||||
ciaset->tik.formatVersion = 1;
|
||||
|
||||
GenCertChildIssuer(ciaset->tik.issuer,ciaset->keys->certs.xsCert);
|
||||
|
||||
// Tmd Stuff
|
||||
if(usrset->cia.contentId[0] > MAX_U32)
|
||||
ciaset->content.id[0] = u32GetRand();
|
||||
else
|
||||
ciaset->content.id[0] = usrset->cia.contentId[0];
|
||||
|
||||
ciaset->tmd.formatVersion = 1;
|
||||
ciaset->tmd.accessRights = 0;
|
||||
GenCertChildIssuer(ciaset->tmd.issuer,ciaset->keys->certs.cpCert);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset)
|
||||
{
|
||||
/* Sanity Checks */
|
||||
if(!ciaset->ciaSections.content.buffer)
|
||||
return CIA_NO_NCCH0;
|
||||
|
||||
u8 *ncch0 = (u8*)(ciaset->ciaSections.content.buffer+ncch0_offset);
|
||||
|
||||
if(!IsNcch(NULL,ncch0)){
|
||||
fprintf(stderr,"[CIA ERROR] Content0 is not NCCH\n");
|
||||
return CIA_INVALID_NCCH0;
|
||||
}
|
||||
|
||||
/* Get Ncch0 Header */
|
||||
ncch_hdr *hdr = (ncch_hdr*)ncch0;
|
||||
ciaset->content.IsCfa = IsCfa(hdr);
|
||||
|
||||
ciaset->content.offset[0] = 0;
|
||||
ciaset->content.size[0] = align(GetNcchSize(hdr),0x10);
|
||||
ciaset->content.totalSize = ciaset->content.size[0];
|
||||
|
||||
/* Get Ncch0 Import Context */
|
||||
ncch_info *info = calloc(1,sizeof(ncch_info));
|
||||
if(!info){
|
||||
fprintf(stderr,"[CIA ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
GetNcchInfo(info,hdr);
|
||||
|
||||
/* Verify Ncch0 (Sig&Hash Checks) */
|
||||
ciaset->content.keyFound = true;
|
||||
int result = VerifyNcch(ncch0, ciaset->keys, false, ciaset->verbose == false);
|
||||
if(result == UNABLE_TO_LOAD_NCCH_KEY){
|
||||
ciaset->content.keyFound = false;
|
||||
ciaset->common.useCxiRemasterVersion = false;
|
||||
if(!ciaset->content.IsCfa){
|
||||
fprintf(stderr,"[CIA WARNING] CXI AES Key could not be loaded\n");
|
||||
fprintf(stderr," Meta Region, SaveDataSize, Remaster Version cannot be obtained\n");
|
||||
}
|
||||
}
|
||||
else if(result != 0){
|
||||
fprintf(stderr,"[CIA ERROR] Content 0 Is Corrupt (res = %d)\n",result);
|
||||
return CIA_INVALID_NCCH0;
|
||||
}
|
||||
|
||||
/* Gen Settings From Ncch0 */
|
||||
ciaset->common.titleId = u8_to_u64(hdr->titleId,LE);
|
||||
|
||||
|
||||
/* Getting NCCH key */
|
||||
u8 *ncchkey = NULL;
|
||||
if(ciaset->content.keyFound && IsNcchEncrypted(hdr)){
|
||||
SetNcchKeys(ciaset->keys,hdr);
|
||||
ncchkey = ciaset->keys->aes.ncchKey0;
|
||||
if(ciaset->verbose){
|
||||
printf("[CIA] NCCH AES keys:\n");
|
||||
memdump(stdout," > key0: ",ciaset->keys->aes.ncchKey0,AES_128_KEY_SIZE);
|
||||
memdump(stdout," > key1: ",ciaset->keys->aes.ncchKey1,AES_128_KEY_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get TMD Data from NCCH */
|
||||
result = GetTmdDataFromNcch(ciaset,ncch0,info,ncchkey);
|
||||
if(result) goto finish;
|
||||
/* Get Meta Region from NCCH */
|
||||
result = GetMetaRegion(ciaset,ncch0,info,ncchkey);
|
||||
/* Finish */
|
||||
finish:
|
||||
/* Return */
|
||||
free(info);
|
||||
return result;
|
||||
}
|
||||
|
||||
int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *key)
|
||||
{
|
||||
int result = 0;
|
||||
extended_hdr *exhdr = NULL;
|
||||
|
||||
if(!ciaset->content.IsCfa && ciaset->content.keyFound){
|
||||
exhdr = malloc(sizeof(extended_hdr));
|
||||
memcpy(exhdr,ncch+ncch_ctx->exhdrOffset,sizeof(extended_hdr));
|
||||
if(key != NULL)
|
||||
CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),0,ncch_ctx->titleId,key,ncch_exhdr);
|
||||
}
|
||||
|
||||
// If this title is a Patch or a CFA SaveData size cannot be set in TMD
|
||||
if( IsPatch(GetTidCategory(ciaset->common.titleId)) || ciaset->content.IsCfa )
|
||||
ciaset->tmd.savedataSize = 0;
|
||||
// Otherwise read Savedata size from exheader, but only first word of savesize is read
|
||||
else if(ciaset->content.keyFound)
|
||||
ciaset->tmd.savedataSize = (u32)(GetSaveDataSize_frm_exhdr(exhdr) & MAX_U32);
|
||||
// if it's a title which can have save data, but save data size could not be read from exhdr
|
||||
else if(ciaset->rsf->SystemControlInfo.SaveDataSize){
|
||||
u64 size = 0;
|
||||
GetSaveDataSizeFromString(&size,ciaset->rsf->SystemControlInfo.SaveDataSize,"CIA");
|
||||
ciaset->tmd.savedataSize = (u32)(size & MAX_U32);
|
||||
}
|
||||
// the user has neglected to provide any means of determining the savedata size
|
||||
else
|
||||
ciaset->tmd.savedataSize = 0;
|
||||
|
||||
// Process title version
|
||||
// If this is a CXI, and we have to pull version major from exheader...
|
||||
if(!ciaset->content.IsCfa && ciaset->common.useCxiRemasterVersion){
|
||||
// Setting remaster ver
|
||||
ciaset->common.titleVersion[VER_MAJOR] = GetRemasterVersion_frm_exhdr(exhdr);
|
||||
}
|
||||
|
||||
// Calculate u16 title version
|
||||
ciaset->tmd.version = ciaset->tik.version = SetupVersion(ciaset->common.titleVersion[VER_MAJOR],ciaset->common.titleVersion[VER_MINOR],ciaset->common.titleVersion[VER_MICRO]);
|
||||
|
||||
free(exhdr);
|
||||
return result;
|
||||
}
|
||||
|
||||
int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_info *info, u8 *key)
|
||||
{
|
||||
extended_hdr *exhdr;
|
||||
exefs_hdr *exefsHdr;
|
||||
cia_metadata *hdr;
|
||||
u32 icon_size, icon_offset;
|
||||
|
||||
// Do not proceed if this is a CFA or can't be decrypted
|
||||
if(ciaset->content.IsCfa || !ciaset->content.keyFound)
|
||||
return 0;
|
||||
|
||||
// Obtain (&decrypt) exheader
|
||||
exhdr = malloc(sizeof(extended_hdr));
|
||||
memcpy(exhdr,ncch+info->exhdrOffset,sizeof(extended_hdr));
|
||||
if(key != NULL)
|
||||
CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),0,info->titleId,key,ncch_exhdr);
|
||||
|
||||
// Obtain (&decrypt) exefs header
|
||||
exefsHdr = malloc(sizeof(exefs_hdr));
|
||||
memcpy(exefsHdr,ncch+info->exefsOffset,sizeof(exefs_hdr));
|
||||
if(key != NULL)
|
||||
CryptNcchRegion((u8*)exefsHdr,sizeof(exefs_hdr),0,info->titleId,key,ncch_exefs);
|
||||
|
||||
// Only continue if icon exists
|
||||
if(!DoesExeFsSectionExist("icon",(u8*)exefsHdr))
|
||||
goto cleanup;
|
||||
|
||||
icon_size = GetExeFsSectionSize("icon",(u8*)exefsHdr);
|
||||
icon_offset = GetExeFsSectionOffset("icon",(u8*)exefsHdr);
|
||||
|
||||
// Allocating memory for Meta region
|
||||
ciaset->ciaSections.meta.size = sizeof(cia_metadata) + icon_size;
|
||||
ciaset->ciaSections.meta.buffer = calloc(1,ciaset->ciaSections.meta.size);
|
||||
if(!ciaset->ciaSections.meta.buffer){
|
||||
fprintf(stderr,"[CIA ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
|
||||
// Writing Dependency List & Core Version to Meta region
|
||||
hdr = (cia_metadata*)ciaset->ciaSections.meta.buffer;
|
||||
GetDependencyList_frm_exhdr(hdr->dependencyList,exhdr);
|
||||
GetCoreVersion_frm_exhdr(hdr->coreVersion,exhdr);
|
||||
|
||||
// Writing Icon data to Meta region
|
||||
u8 *iconPos = (ciaset->ciaSections.meta.buffer + sizeof(cia_metadata));
|
||||
memcpy(iconPos,ncch+info->exefsOffset+icon_offset,icon_size);
|
||||
if(key != NULL)
|
||||
CryptNcchRegion(iconPos,icon_size,icon_offset,info->titleId,key,ncch_exefs);
|
||||
|
||||
cleanup:
|
||||
free(exefsHdr);
|
||||
free(exhdr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetContentFilePtrs(cia_settings *ciaset, user_settings *usrset)
|
||||
{
|
||||
ciaset->content.filePtrs = malloc(sizeof(FILE*)*CIA_MAX_CONTENT);
|
||||
if(!ciaset->content.filePtrs){
|
||||
fprintf(stderr,"[CIA ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
memset(ciaset->content.filePtrs,0,sizeof(FILE*)*CIA_MAX_CONTENT);
|
||||
int j = 1;
|
||||
ncch_hdr *hdr = malloc(sizeof(ncch_hdr));
|
||||
for(int i = 1; i < CIA_MAX_CONTENT; i++){
|
||||
if(usrset->common.contentPath[i]){
|
||||
if(!AssertFile(usrset->common.contentPath[i])){
|
||||
fprintf(stderr,"[CIA ERROR] Failed to open \"%s\"\n",usrset->common.contentPath[i]);
|
||||
return FAILED_TO_OPEN_FILE;
|
||||
}
|
||||
ciaset->content.fileSize[j] = GetFileSize64(usrset->common.contentPath[i]);
|
||||
ciaset->content.filePtrs[j] = fopen(usrset->common.contentPath[i],"rb");
|
||||
|
||||
if(usrset->cia.contentId[i] > MAX_U32)
|
||||
ciaset->content.id[j] = u32GetRand();
|
||||
else
|
||||
ciaset->content.id[j] = (u32)usrset->cia.contentId[i];
|
||||
|
||||
ciaset->content.index[j] = (u16)i;
|
||||
|
||||
// Get Data from ncch HDR
|
||||
ReadNcchHdr(hdr,ciaset->content.filePtrs[j]);
|
||||
|
||||
// Get Size
|
||||
u64 calcSize = GetNcchSize(hdr);
|
||||
if(calcSize != ciaset->content.fileSize[j]){
|
||||
fprintf(stderr,"[CIA ERROR] \"%s\" is corrupt\n",usrset->common.contentPath[i]);
|
||||
return FAILED_TO_OPEN_FILE;
|
||||
}
|
||||
|
||||
ciaset->content.size[j] = align(calcSize,CIA_CONTENT_ALIGN);
|
||||
ciaset->content.offset[j] = ciaset->content.totalSize;
|
||||
|
||||
ciaset->content.totalSize += ciaset->content.size[j];
|
||||
|
||||
|
||||
// Finish get next content
|
||||
j++;
|
||||
}
|
||||
}
|
||||
free(hdr);
|
||||
ciaset->content.count = j;
|
||||
|
||||
// Check Conflicting IDs
|
||||
for(int i = 0; i < ciaset->content.count; i++){
|
||||
for(j = i+1; j < ciaset->content.count; j++){
|
||||
if(ciaset->content.id[j] == ciaset->content.id[i]){
|
||||
fprintf(stderr,"[CIA ERROR] CIA Content %d and %d, have conflicting IDs\n",ciaset->content.index[j],ciaset->content.index[i]);
|
||||
return CIA_CONFILCTING_CONTENT_IDS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ImportNcchContent(cia_settings *ciaset)
|
||||
{
|
||||
ciaset->ciaSections.content.buffer = realloc(ciaset->ciaSections.content.buffer,ciaset->content.totalSize);
|
||||
if(!ciaset->ciaSections.content.buffer){
|
||||
fprintf(stderr,"[CIA ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
|
||||
ncch_hdr *ncch0hdr = (ncch_hdr*)ciaset->ciaSections.content.buffer;
|
||||
for(int i = 1; i < ciaset->content.count; i++){
|
||||
// Import
|
||||
u8 *ncchpos = (u8*)(ciaset->ciaSections.content.buffer+ciaset->content.offset[i]);
|
||||
|
||||
ReadFile64(ncchpos, ciaset->content.fileSize[i], 0, ciaset->content.filePtrs[i]);
|
||||
if(ModifyNcchIds(ncchpos, NULL, ncch0hdr->programId, ciaset->keys) != 0)
|
||||
return -1;
|
||||
|
||||
// Set Additional Flags
|
||||
if(ciaset->content.IsDlc)
|
||||
ciaset->content.flags[i] |= content_Optional;
|
||||
|
||||
//if(unknown condition)
|
||||
// ciaset->content.flags[i] |= content_Shared;
|
||||
}
|
||||
|
||||
ciaset->ciaSections.content.size = ciaset->content.totalSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetSettingsFromSrl(cia_settings *ciaset)
|
||||
{
|
||||
srl_hdr *hdr = (srl_hdr*)ciaset->ciaSections.content.buffer;
|
||||
if(!hdr || ciaset->ciaSections.content.size < sizeof(srl_hdr)) {
|
||||
fprintf(stderr,"[CIA ERROR] Invalid TWL SRL File\n");
|
||||
return FAILED_TO_IMPORT_FILE;
|
||||
}
|
||||
|
||||
// Check if TWL SRL File
|
||||
if(u8_to_u16(&hdr->title_id[6],LE) != 0x0003){
|
||||
fprintf(stderr,"[CIA ERROR] Invalid TWL SRL File\n");
|
||||
return FAILED_TO_IMPORT_FILE;
|
||||
}
|
||||
|
||||
// Generate and store Converted TitleID
|
||||
ciaset->common.titleId = ConvertTwlIdToCtrId(u8_to_u64(hdr->title_id,LE));
|
||||
|
||||
// Get TWL Flag
|
||||
ciaset->tmd.twlFlag = ((hdr->reserved_flags[3] & 6) >> 1);
|
||||
|
||||
// Get Remaster Version
|
||||
u16 version = SetupVersion(hdr->romVersion,ciaset->common.titleVersion[1],0);
|
||||
ciaset->tik.version = version;
|
||||
ciaset->tmd.version = version;
|
||||
|
||||
// Get SaveDataSize (Public and Private)
|
||||
ciaset->tmd.savedataSize = u8_to_u32(hdr->pubSaveDataSize,LE);
|
||||
ciaset->tmd.privSavedataSize = u8_to_u32(hdr->privSaveDataSize,LE);
|
||||
|
||||
// Setting CIA Content Settings
|
||||
ciaset->content.count = 1;
|
||||
ciaset->content.offset[0] = 0;
|
||||
ciaset->content.size[0] = ciaset->ciaSections.content.size;
|
||||
ciaset->content.totalSize = ciaset->ciaSections.content.size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetSettingsFromCci(cia_settings *ciaset)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if(!IsCci(ciaset->ciaSections.content.buffer)){
|
||||
fprintf(stderr,"[CIA ERROR] Invalid CCI file\n");
|
||||
return FAILED_TO_IMPORT_FILE;
|
||||
}
|
||||
|
||||
u32 ncch0_offset = GetPartitionOffset(ciaset->ciaSections.content.buffer,0);
|
||||
if(!ncch0_offset){
|
||||
fprintf(stderr,"[CIA ERROR] Invalid CCI file (invalid ncch0)\n");
|
||||
return FAILED_TO_IMPORT_FILE;
|
||||
}
|
||||
|
||||
result = GetSettingsFromNcch0(ciaset, ncch0_offset);
|
||||
if(result){
|
||||
fprintf(stderr,"Import of Ncch 0 failed(%d)\n",result);
|
||||
return result;
|
||||
}
|
||||
int j = 1;
|
||||
|
||||
u64 cciContentOffsets[CCI_MAX_CONTENT];
|
||||
cciContentOffsets[0] = ncch0_offset;
|
||||
for(int i = 1; i < 8; i++){
|
||||
if(GetPartitionSize(ciaset->ciaSections.content.buffer,i)){
|
||||
ncch_hdr *ncchHdr = (ncch_hdr*)GetPartition(ciaset->ciaSections.content.buffer, i);
|
||||
|
||||
if(IsUpdateCfa(ncchHdr) && !ciaset->content.includeUpdateNcch)
|
||||
continue;
|
||||
|
||||
cciContentOffsets[j] = GetPartitionOffset(ciaset->ciaSections.content.buffer,i);
|
||||
|
||||
// Get Size
|
||||
ciaset->content.size[j] = GetPartitionSize(ciaset->ciaSections.content.buffer,i);
|
||||
ciaset->content.offset[j] = ciaset->content.totalSize;
|
||||
|
||||
ciaset->content.totalSize += ciaset->content.size[j];
|
||||
|
||||
// Get ID
|
||||
ciaset->content.id[j] = u32GetRand();
|
||||
|
||||
// Get Index
|
||||
ciaset->content.index[j] = i;
|
||||
|
||||
// Increment Content Count
|
||||
j++;
|
||||
}
|
||||
}
|
||||
ciaset->content.count = j;
|
||||
|
||||
for(int i = 0; i < ciaset->content.count; i++){ // Re-organising content positions in memory
|
||||
u8 *cci_pos = (ciaset->ciaSections.content.buffer + cciContentOffsets[i]);
|
||||
u8 *cia_pos = (ciaset->ciaSections.content.buffer + ciaset->content.offset[i]);
|
||||
memcpy(cia_pos,cci_pos,ciaset->content.size[i]);
|
||||
}
|
||||
ciaset->ciaSections.content.size = ciaset->content.totalSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 SetupVersion(u16 major, u16 minor, u16 micro)
|
||||
{
|
||||
return (((major << 10) & 0xFC00) | ((minor << 4) & 0x3F0) | (micro & 0xf));
|
||||
}
|
||||
|
||||
void GetContentHashes(cia_settings *ciaset)
|
||||
{
|
||||
for (int i = 0; i < ciaset->content.count; i++) {
|
||||
if (ciaset->verbose)
|
||||
printf("[CIA] Hashing content %d... ", i);
|
||||
ShaCalc(ciaset->ciaSections.content.buffer + ciaset->content.offset[i], ciaset->content.size[i], ciaset->content.hash[i], CTR_SHA_256);
|
||||
if (ciaset->verbose)
|
||||
printf("Done!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptContent(cia_settings *ciaset)
|
||||
{
|
||||
for(int i = 0; i < ciaset->content.count; i++){
|
||||
if (ciaset->verbose)
|
||||
printf("[CIA] Encrypting content %d... ", i);
|
||||
|
||||
ciaset->content.flags[i] |= content_Encrypted;
|
||||
u8 *content = ciaset->ciaSections.content.buffer+ciaset->content.offset[i];
|
||||
CryptContent(content, content, ciaset->content.size[i], ciaset->common.titleKey, i, ENC);
|
||||
|
||||
if (ciaset->verbose)
|
||||
printf("Done!\n");
|
||||
}
|
||||
}
|
||||
|
||||
int BuildCiaCertChain(cia_settings *ciaset)
|
||||
{
|
||||
ciaset->ciaSections.certChain.size = GetCertSize(ciaset->keys->certs.caCert) + GetCertSize(ciaset->keys->certs.xsCert) + GetCertSize(ciaset->keys->certs.cpCert);
|
||||
ciaset->ciaSections.certChain.buffer = malloc(ciaset->ciaSections.certChain.size);
|
||||
if(!ciaset->ciaSections.certChain.buffer) {
|
||||
fprintf(stderr,"[CIA ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
memcpy(ciaset->ciaSections.certChain.buffer,ciaset->keys->certs.caCert,GetCertSize(ciaset->keys->certs.caCert));
|
||||
memcpy((ciaset->ciaSections.certChain.buffer+GetCertSize(ciaset->keys->certs.caCert)),ciaset->keys->certs.xsCert,GetCertSize(ciaset->keys->certs.xsCert));
|
||||
memcpy((ciaset->ciaSections.certChain.buffer+GetCertSize(ciaset->keys->certs.caCert)+GetCertSize(ciaset->keys->certs.xsCert)),ciaset->keys->certs.cpCert,GetCertSize(ciaset->keys->certs.cpCert));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BuildCiaHdr(cia_settings *ciaset)
|
||||
{
|
||||
// Allocating memory for header
|
||||
ciaset->ciaSections.ciaHdr.size = sizeof(cia_hdr);
|
||||
ciaset->ciaSections.ciaHdr.buffer = malloc(ciaset->ciaSections.ciaHdr.size);
|
||||
if(!ciaset->ciaSections.ciaHdr.buffer){
|
||||
fprintf(stderr,"[CIA ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
|
||||
cia_hdr *hdr = (cia_hdr*)ciaset->ciaSections.ciaHdr.buffer;
|
||||
|
||||
// Clearing
|
||||
memset(hdr,0,sizeof(cia_hdr));
|
||||
|
||||
// Setting Data
|
||||
u32_to_u8(hdr->hdrSize,sizeof(cia_hdr),LE);
|
||||
u16_to_u8(hdr->type,0x0,LE);
|
||||
u16_to_u8(hdr->version,0x0,LE);
|
||||
u32_to_u8(hdr->certChainSize,ciaset->ciaSections.certChain.size,LE);
|
||||
u32_to_u8(hdr->tikSize,ciaset->ciaSections.tik.size,LE);
|
||||
u32_to_u8(hdr->tmdSize,ciaset->ciaSections.tmd.size,LE);
|
||||
u32_to_u8(hdr->metaSize,ciaset->ciaSections.meta.size,LE);
|
||||
u64_to_u8(hdr->contentSize,ciaset->content.totalSize,LE);
|
||||
|
||||
// Recording Offsets
|
||||
ciaset->ciaSections.certChainOffset = align(sizeof(cia_hdr),0x40);
|
||||
ciaset->ciaSections.tikOffset = align(ciaset->ciaSections.certChainOffset+ciaset->ciaSections.certChain.size,0x40);
|
||||
ciaset->ciaSections.tmdOffset = align(ciaset->ciaSections.tikOffset+ciaset->ciaSections.tik.size,0x40);
|
||||
ciaset->ciaSections.contentOffset = align(ciaset->ciaSections.tmdOffset+ciaset->ciaSections.tmd.size,0x40);
|
||||
ciaset->ciaSections.metaOffset = align(ciaset->ciaSections.contentOffset+ciaset->content.totalSize,0x40);
|
||||
|
||||
for(int i = 0; i < ciaset->content.count; i++)
|
||||
hdr->contentIndex[ciaset->content.index[i]/8] |= 0x80 >> (ciaset->content.index[i] & 7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WriteCiaToFile(cia_settings *ciaset)
|
||||
{
|
||||
if (ciaset->verbose) {
|
||||
printf("[CIA] Writing to file... ");
|
||||
}
|
||||
WriteBuffer(ciaset->ciaSections.ciaHdr.buffer,ciaset->ciaSections.ciaHdr.size,0,ciaset->out);
|
||||
WriteBuffer(ciaset->ciaSections.certChain.buffer,ciaset->ciaSections.certChain.size,ciaset->ciaSections.certChainOffset,ciaset->out);
|
||||
WriteBuffer(ciaset->ciaSections.tik.buffer,ciaset->ciaSections.tik.size,ciaset->ciaSections.tikOffset,ciaset->out);
|
||||
WriteBuffer(ciaset->ciaSections.tmd.buffer,ciaset->ciaSections.tmd.size,ciaset->ciaSections.tmdOffset,ciaset->out);
|
||||
WriteBuffer(ciaset->ciaSections.content.buffer,ciaset->ciaSections.content.size,ciaset->ciaSections.contentOffset,ciaset->out);
|
||||
WriteBuffer(ciaset->ciaSections.meta.buffer,ciaset->ciaSections.meta.size,ciaset->ciaSections.metaOffset,ciaset->out);
|
||||
|
||||
if (ciaset->verbose) {
|
||||
printf("Done!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CryptContent(u8 *input, u8 *output, u64 size, u8 *title_key, u16 index, u8 mode)
|
||||
{
|
||||
//generating IV
|
||||
u8 iv[16];
|
||||
clrmem(&iv,16);
|
||||
iv[0] = (index >> 8) & 0xff;
|
||||
iv[1] = index & 0xff;
|
||||
//Crypting content
|
||||
AesCbcCrypt(title_key,iv,input,output,size,mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsCia(u8 *cia)
|
||||
{
|
||||
if(!cia)
|
||||
return false;
|
||||
|
||||
cia_hdr *hdr = (cia_hdr*)cia;
|
||||
|
||||
if(u8_to_u32(hdr->hdrSize,LE) != sizeof(cia_hdr) || u8_to_u16(hdr->type,LE) != 0 || u8_to_u16(hdr->version,LE) != 0)
|
||||
return false;
|
||||
|
||||
if(!GetCiaCertSize(hdr) || !GetCiaTikSize(hdr) || !GetCiaTmdSize(hdr) || !GetCiaContentSize(hdr))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 GetCiaCertOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 hdrSize = u8_to_u32(hdr->hdrSize,LE);
|
||||
return align(hdrSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaCertSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u32(hdr->certChainSize,LE);
|
||||
}
|
||||
|
||||
u64 GetCiaTikOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 certOffset = GetCiaCertOffset(hdr);
|
||||
u64 certSize = GetCiaCertSize(hdr);
|
||||
return align(certOffset + certSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaTikSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u32(hdr->tikSize,LE);
|
||||
}
|
||||
|
||||
u64 GetCiaTmdOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 tikOffset = GetCiaTikOffset(hdr);
|
||||
u64 tikSize = GetCiaTikSize(hdr);
|
||||
return align(tikOffset + tikSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaTmdSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u32(hdr->tmdSize,LE);
|
||||
}
|
||||
|
||||
u64 GetCiaContentOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 tmdOffset = GetCiaTmdOffset(hdr);
|
||||
u64 tmdSize = GetCiaTmdSize(hdr);
|
||||
return align(tmdOffset + tmdSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaContentSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u64(hdr->contentSize,LE);
|
||||
}
|
||||
|
||||
u64 GetCiaMetaOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 contentOffset = GetCiaContentOffset(hdr);
|
||||
u64 contentSize = GetCiaContentSize(hdr);
|
||||
return align(contentOffset + contentSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaMetaSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u32(hdr->metaSize,LE);
|
||||
}
|
||||
|
||||
u8* GetCiaCert(u8 *cia)
|
||||
{
|
||||
return cia + GetCiaCertOffset((cia_hdr*)cia);
|
||||
}
|
||||
|
||||
u8* GetCiaTik(u8 *cia)
|
||||
{
|
||||
return cia + GetCiaTikOffset((cia_hdr*)cia);
|
||||
}
|
||||
|
||||
u8* GetCiaTmd(u8 *cia)
|
||||
{
|
||||
return cia + GetCiaTmdOffset((cia_hdr*)cia);
|
||||
}
|
||||
|
||||
u8* GetCiaContent(u8 *cia)
|
||||
{
|
||||
return cia + GetCiaContentOffset((cia_hdr*)cia);
|
||||
}
|
||||
|
||||
u8* GetCiaMeta(u8 *cia)
|
||||
{
|
||||
if(GetCiaMetaSize((cia_hdr*)cia))
|
||||
return cia + GetCiaMetaOffset((cia_hdr*)cia);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
// Structs
|
||||
typedef struct
|
||||
{
|
||||
u8 hdrSize[4];
|
||||
u8 type[2];
|
||||
u8 version[2];
|
||||
u8 certChainSize[4];
|
||||
u8 tikSize[4];
|
||||
u8 tmdSize[4];
|
||||
u8 metaSize[4];
|
||||
u8 contentSize[8];
|
||||
u8 contentIndex[0x2000];
|
||||
} cia_hdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 dependencyList[0x30*0x8];
|
||||
u8 padding0[0x180];
|
||||
u8 coreVersion[4];
|
||||
u8 padding1[0xfc];
|
||||
} cia_metadata;
|
||||
|
||||
int CryptContent(u8 *input, u8 *output, u64 size, u8 *title_key, u16 index, u8 mode);
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
#include "cia.h"
|
||||
|
||||
// Enums
|
||||
typedef enum
|
||||
{
|
||||
CIA_NO_NCCH0 = -1,
|
||||
CIA_INVALID_NCCH0 = -2,
|
||||
CIA_CONFILCTING_CONTENT_IDS = -3,
|
||||
} cia_errors;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 *inFile;
|
||||
u64 inFileSize;
|
||||
|
||||
FILE *out;
|
||||
|
||||
rsf_settings *rsf;
|
||||
keys_struct *keys;
|
||||
|
||||
bool verbose;
|
||||
|
||||
struct{
|
||||
bool useCxiRemasterVersion;
|
||||
u64 titleId;
|
||||
u16 titleVersion[3];
|
||||
u8 titleKey[16];
|
||||
} common;
|
||||
|
||||
|
||||
struct{
|
||||
u8 caCrlVersion;
|
||||
u8 signerCrlVersion;
|
||||
} cert;
|
||||
|
||||
struct{
|
||||
u8 issuer[0x40];
|
||||
u8 formatVersion;
|
||||
|
||||
u16 version;
|
||||
|
||||
u64 ticketId;
|
||||
u32 deviceId;
|
||||
u8 licenceType;
|
||||
u8 audit;
|
||||
u32 eshopAccId;
|
||||
} tik;
|
||||
|
||||
struct{
|
||||
u8 issuer[0x40];
|
||||
u8 formatVersion;
|
||||
|
||||
u16 version;
|
||||
u32 accessRights;
|
||||
|
||||
u32 titleType;
|
||||
u32 savedataSize;
|
||||
u32 privSavedataSize;
|
||||
u8 twlFlag;
|
||||
} tmd;
|
||||
|
||||
struct{
|
||||
bool IsCfa;
|
||||
bool IsDlc;
|
||||
bool encryptCia;
|
||||
bool includeUpdateNcch; // for cci -> cia conversions
|
||||
|
||||
bool keyFound;
|
||||
|
||||
FILE **filePtrs;
|
||||
u64 fileSize[CIA_MAX_CONTENT];
|
||||
|
||||
/* Misc Records */
|
||||
u16 count;
|
||||
u64 offset[CIA_MAX_CONTENT];
|
||||
u64 totalSize;
|
||||
|
||||
/* Content Chunk Records */
|
||||
u64 size[CIA_MAX_CONTENT];
|
||||
u16 index[CIA_MAX_CONTENT];
|
||||
u16 flags[CIA_MAX_CONTENT];
|
||||
u32 id[CIA_MAX_CONTENT];
|
||||
u8 hash[CIA_MAX_CONTENT][0x20];
|
||||
} content;
|
||||
|
||||
struct{
|
||||
buffer_struct ciaHdr;
|
||||
|
||||
u32 certChainOffset;
|
||||
buffer_struct certChain;
|
||||
|
||||
u32 tikOffset;
|
||||
buffer_struct tik;
|
||||
|
||||
u32 tmdOffset;
|
||||
buffer_struct tmd;
|
||||
|
||||
u32 metaOffset;
|
||||
buffer_struct meta;
|
||||
|
||||
u64 contentOffset;
|
||||
buffer_struct content;
|
||||
} ciaSections;
|
||||
} cia_settings;
|
||||
|
||||
// Public Prototypes
|
||||
int build_CIA(user_settings *usrset);
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "cia.h"
|
||||
|
||||
// Cia Read Functions
|
||||
bool IsCia(u8 *cia);
|
||||
u64 GetCiaCertOffset(cia_hdr *hdr);
|
||||
u64 GetCiaCertSize(cia_hdr *hdr);
|
||||
u64 GetCiaTikOffset(cia_hdr *hdr);
|
||||
u64 GetCiaTikSize(cia_hdr *hdr);
|
||||
u64 GetCiaTmdOffset(cia_hdr *hdr);
|
||||
u64 GetCiaTmdSize(cia_hdr *hdr);
|
||||
u64 GetCiaContentOffset(cia_hdr *hdr);
|
||||
u64 GetCiaContentSize(cia_hdr *hdr);
|
||||
u64 GetCiaMetaOffset(cia_hdr *hdr);
|
||||
u64 GetCiaMetaSize(cia_hdr *hdr);
|
||||
|
||||
u8* GetCiaCert(u8 *cia);
|
||||
u8* GetCiaTik(u8 *cia);
|
||||
u8* GetCiaTmd(u8 *cia);
|
||||
u8* GetCiaContent(u8 *cia);
|
||||
u8* GetCiaMeta(u8 *cia);
|
||||
@@ -0,0 +1,316 @@
|
||||
#include "lib.h"
|
||||
#include "elf.h"
|
||||
#include "ncch_build.h"
|
||||
#include "exheader_read.h"
|
||||
#include "code.h"
|
||||
|
||||
#include <blz.h>
|
||||
|
||||
const u32 CTR_PAGE_SIZE = 0x1000;
|
||||
const u32 DEFAULT_STACK_SIZE = 0x4000; // 10KB
|
||||
|
||||
typedef struct code_segment
|
||||
{
|
||||
u32 address;
|
||||
u32 memSize;
|
||||
u32 fileSize;
|
||||
u32 pageNum;
|
||||
const u8 *data;
|
||||
} code_segment;
|
||||
|
||||
u32 SizeToPage(u32 memorySize)
|
||||
{
|
||||
return align(memorySize, CTR_PAGE_SIZE) / CTR_PAGE_SIZE;
|
||||
}
|
||||
|
||||
u32 PageToSize(u32 pageNum)
|
||||
{
|
||||
return pageNum * CTR_PAGE_SIZE;
|
||||
}
|
||||
|
||||
int ImportPlainRegionFromFile(ncch_settings *set)
|
||||
{
|
||||
set->sections.plainRegion.size = align(set->componentFilePtrs.plainregionSize, set->options.blockSize);
|
||||
set->sections.plainRegion.buffer = calloc(set->sections.plainRegion.size, 1);
|
||||
if (!set->sections.plainRegion.buffer) { fprintf(stderr, "[ELF ERROR] Not enough memory\n"); return MEM_ERROR; }
|
||||
ReadFile64(set->sections.plainRegion.buffer, set->componentFilePtrs.plainregionSize, 0, set->componentFilePtrs.plainregion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ImportExeFsCodeBinaryFromFile(ncch_settings *set)
|
||||
{
|
||||
u32 size = set->componentFilePtrs.codeSize;
|
||||
u8 *buffer = malloc(size);
|
||||
if (!buffer) {
|
||||
fprintf(stderr, "[CODE ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
ReadFile64(buffer, size, 0, set->componentFilePtrs.code);
|
||||
|
||||
set->exefsSections.code.size = set->componentFilePtrs.codeSize;
|
||||
set->exefsSections.code.buffer = malloc(set->exefsSections.code.size);
|
||||
if (!set->exefsSections.code.buffer) { fprintf(stderr, "[ELF ERROR] Not enough memory\n"); return MEM_ERROR; }
|
||||
ReadFile64(set->exefsSections.code.buffer, set->exefsSections.code.size, 0, set->componentFilePtrs.code);
|
||||
if (set->options.CompressCode) {
|
||||
if (set->options.verbose)
|
||||
printf("[CODE] Compressing code... ");
|
||||
u32 new_len;
|
||||
set->exefsSections.code.buffer = BLZ_Code(buffer, size, &new_len, BLZ_NORMAL);
|
||||
set->exefsSections.code.size = new_len;
|
||||
free(buffer);
|
||||
if (set->options.verbose)
|
||||
printf("Done!\n");
|
||||
}
|
||||
else {
|
||||
set->exefsSections.code.size = size;
|
||||
set->exefsSections.code.buffer = buffer;
|
||||
}
|
||||
|
||||
size = set->componentFilePtrs.exhdrSize;
|
||||
if (size < sizeof(extended_hdr)) {
|
||||
fprintf(stderr, "[CODE ERROR] Exheader code info template is too small\n");
|
||||
return FAILED_TO_IMPORT_FILE;
|
||||
}
|
||||
extended_hdr *exhdr = malloc(size);
|
||||
if (!exhdr) {
|
||||
fprintf(stderr, "[CODE ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
ReadFile64(exhdr, size, 0, set->componentFilePtrs.exhdr);
|
||||
|
||||
/* Setting code_segment data */
|
||||
set->codeDetails.textAddress = u8_to_u32(exhdr->codeSetInfo.text.address, LE);
|
||||
set->codeDetails.textMaxPages = u8_to_u32(exhdr->codeSetInfo.text.numMaxPages, LE);
|
||||
set->codeDetails.textSize = u8_to_u32(exhdr->codeSetInfo.text.codeSize, LE);
|
||||
|
||||
set->codeDetails.roAddress = u8_to_u32(exhdr->codeSetInfo.rodata.address, LE);
|
||||
set->codeDetails.roMaxPages = u8_to_u32(exhdr->codeSetInfo.rodata.numMaxPages, LE);
|
||||
set->codeDetails.roSize = u8_to_u32(exhdr->codeSetInfo.rodata.codeSize, LE);
|
||||
|
||||
set->codeDetails.rwAddress = u8_to_u32(exhdr->codeSetInfo.data.address, LE);
|
||||
set->codeDetails.rwMaxPages = u8_to_u32(exhdr->codeSetInfo.data.numMaxPages, LE);
|
||||
set->codeDetails.rwSize = u8_to_u32(exhdr->codeSetInfo.data.codeSize, LE);
|
||||
|
||||
set->codeDetails.bssSize = u8_to_u32(exhdr->codeSetInfo.bssSize, LE);
|
||||
|
||||
set->codeDetails.stackSize = u8_to_u32(exhdr->codeSetInfo.stackSize, LE);
|
||||
|
||||
free(exhdr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ImportPlainRegionFromElf(elf_context *elf, ncch_settings *set)
|
||||
{
|
||||
elf_segment segment = elf_GetSegments(elf)[elf_SegmentNum(elf) - 1];
|
||||
|
||||
/* Check last segment
|
||||
If the last segment is RO segment, this must be an SDK .module_id segment */
|
||||
if (segment.flags != PF_RODATA) {
|
||||
/* not a RO segment */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (segment.fileSize > 0) {
|
||||
/* Creating Output Buffer */
|
||||
set->sections.plainRegion.size = align(segment.fileSize, set->options.blockSize);
|
||||
set->sections.plainRegion.buffer = calloc(set->sections.plainRegion.size, 1);
|
||||
if (!set->sections.plainRegion.buffer) { fprintf(stderr, "[CODE ERROR] Not enough memory\n"); return MEM_ERROR; }
|
||||
|
||||
/* Copy Plain Region */
|
||||
memcpy(set->sections.plainRegion.buffer, segment.ptr, segment.fileSize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CreateCodeSegmentFromElf(code_segment *out, elf_context *elf, u64 segment_flags)
|
||||
{
|
||||
u32 segmentNum = elf_SegmentNum(elf);
|
||||
const elf_segment *segments = elf_GetSegments(elf);
|
||||
|
||||
/* Initialise struct data */
|
||||
out->address = 0;
|
||||
out->memSize = 0;
|
||||
out->pageNum = 0;
|
||||
out->fileSize = 0;
|
||||
out->data = NULL;
|
||||
|
||||
/* Find segment */
|
||||
for (u16 i = 0; i < segmentNum; i++) {
|
||||
/* Skip SDK ELF .module_id segment
|
||||
The last segment should always be data in valid ELFs,
|
||||
unless this is an SDK ELF with .module_id segment */
|
||||
if (i == segmentNum-1 && segments[i].flags == PF_RODATA)
|
||||
continue;
|
||||
|
||||
/* Found segment */
|
||||
if ((segments[i].flags & ~PF_CTRSDK) == segment_flags && segments[i].type == PT_LOAD) {
|
||||
out->address = segments[i].vAddr;
|
||||
out->memSize = segments[i].memSize;
|
||||
out->fileSize = segments[i].fileSize;
|
||||
out->pageNum = SizeToPage(out->fileSize);
|
||||
out->data = segments[i].ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CreateExeFsCode(elf_context *elf, ncch_settings *set)
|
||||
{
|
||||
/* Getting Code Segments */
|
||||
code_segment text;
|
||||
code_segment rodata;
|
||||
code_segment rwdata;
|
||||
|
||||
CreateCodeSegmentFromElf(&text, elf, PF_TEXT);
|
||||
CreateCodeSegmentFromElf(&rodata, elf, PF_RODATA);
|
||||
CreateCodeSegmentFromElf(&rwdata, elf, PF_DATA);
|
||||
|
||||
/* Checking the existence of essential ELF Segments */
|
||||
if (!text.fileSize) return NOT_FIND_TEXT_SEGMENT;
|
||||
if (!rwdata.fileSize) return NOT_FIND_DATA_SEGMENT;
|
||||
|
||||
/* Calculating BSS size */
|
||||
set->codeDetails.bssSize = rwdata.memSize - rwdata.fileSize;
|
||||
|
||||
/* Allocating Buffer for ExeFs Code */
|
||||
bool noCodePadding = set->options.noCodePadding;
|
||||
u32 size;
|
||||
if (noCodePadding) {
|
||||
size = text.fileSize + rodata.fileSize + rwdata.fileSize;
|
||||
}
|
||||
else {
|
||||
size = PageToSize(text.pageNum + rodata.pageNum + rwdata.pageNum);
|
||||
}
|
||||
u8 *code = calloc(1, size);
|
||||
|
||||
/* Writing Code into Buffer */
|
||||
u8 *textPos = code;
|
||||
u8 *rodataPos = (textPos + (noCodePadding ? text.fileSize : PageToSize(text.pageNum)));
|
||||
u8 *rwdataPos = (rodataPos + (noCodePadding ? rodata.fileSize : PageToSize(rodata.pageNum)));
|
||||
if (text.fileSize) memcpy(textPos, text.data, text.fileSize);
|
||||
if (rodata.fileSize) memcpy(rodataPos, rodata.data, rodata.fileSize);
|
||||
if (rwdata.fileSize) memcpy(rwdataPos, rwdata.data, rwdata.fileSize);
|
||||
|
||||
|
||||
/* Compressing if needed */
|
||||
if (set->options.CompressCode) {
|
||||
if (set->options.verbose)
|
||||
printf("[CODE] Compressing code... ");
|
||||
u32 new_len;
|
||||
set->exefsSections.code.buffer = BLZ_Code(code, size, &new_len, BLZ_NORMAL);
|
||||
set->exefsSections.code.size = new_len;
|
||||
free(code);
|
||||
if (set->options.verbose)
|
||||
printf("Done!\n");
|
||||
}
|
||||
else {
|
||||
set->exefsSections.code.size = size;
|
||||
set->exefsSections.code.buffer = code;
|
||||
}
|
||||
|
||||
/* Setting code_segment data and freeing original buffers */
|
||||
set->codeDetails.textAddress = text.address;
|
||||
set->codeDetails.textMaxPages = text.pageNum;
|
||||
set->codeDetails.textSize = text.fileSize;
|
||||
|
||||
set->codeDetails.roAddress = rodata.address;
|
||||
set->codeDetails.roMaxPages = rodata.pageNum;
|
||||
set->codeDetails.roSize = rodata.fileSize;
|
||||
|
||||
set->codeDetails.rwAddress = rwdata.address;
|
||||
set->codeDetails.rwMaxPages = rwdata.pageNum;
|
||||
set->codeDetails.rwSize = rwdata.fileSize;
|
||||
|
||||
if (set->rsfSet->SystemControlInfo.StackSize)
|
||||
set->codeDetails.stackSize = strtoul(set->rsfSet->SystemControlInfo.StackSize, NULL, 0);
|
||||
else {
|
||||
set->codeDetails.stackSize = DEFAULT_STACK_SIZE;
|
||||
fprintf(stderr, "[CODE WARNING] \"SystemControlInfo/StackSize\" not specified, defaulting to 0x%x bytes\n", DEFAULT_STACK_SIZE);
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void PrintElfContext(elf_context *elf)
|
||||
{
|
||||
printf("[ELF] Program Table Data\n");
|
||||
printf(" Offset: 0x%x\n", elf->programTableOffset);
|
||||
printf(" Size: 0x%x\n", elf->programTableEntrySize);
|
||||
printf(" Count: 0x%x\n", elf->programTableEntryCount);
|
||||
printf("[ELF] Section Table Data\n");
|
||||
printf(" Offset: 0x%x\n", elf->sectionTableOffset);
|
||||
printf(" Size: 0x%x\n", elf->sectionTableEntrySize);
|
||||
printf(" Count: 0x%x\n", elf->sectionTableEntryCount);
|
||||
printf(" Label index: 0x%x\n", elf->sectionHeaderNameEntryIndex);
|
||||
for (int i = 0; i < elf->activeSegments; i++) {
|
||||
printf(" Segment [%d][%s]\n", i, elf->segments[i].name);
|
||||
printf(" > Size(Memory): 0x%x\n", elf->segments[i].header->sizeInMemory);
|
||||
printf(" > Size(File): 0x%x\n", elf->segments[i].header->sizeInFile);
|
||||
printf(" > Address: 0x%x\n", elf->segments[i].vAddr);
|
||||
printf(" > Flags: 0x%x\n", elf->segments[i].header->flags);
|
||||
printf(" > Type: 0x%x\n", elf->segments[i].header->type);
|
||||
printf(" > Sections: %d\n", elf->segments[i].sectionNum);
|
||||
for (int j = 0; j < elf->segments[i].sectionNum; j++)
|
||||
printf(" > Section [%d][%s][0x%x][0x%x]\n", j, elf->segments[i].sections[j].name, elf->segments[i].sections[j].flags, elf->segments[i].sections[j].type);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
int BuildExeFsCode(ncch_settings *set)
|
||||
{
|
||||
int result = 0;
|
||||
if (set->options.IsCfa)
|
||||
return result;
|
||||
|
||||
if (!set->options.IsBuildingCodeSection) { // Import ExeFs Code from file and return
|
||||
if (set->componentFilePtrs.plainregion) // Import PlainRegion from file
|
||||
if ((result = ImportPlainRegionFromFile(set))) return result;
|
||||
return ImportExeFsCodeBinaryFromFile(set);
|
||||
}
|
||||
|
||||
/* Import ELF */
|
||||
u8 *elfFile = malloc(set->componentFilePtrs.elfSize);
|
||||
if (!elfFile) {
|
||||
fprintf(stderr, "[CODE ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
ReadFile64(elfFile, set->componentFilePtrs.elfSize, 0, set->componentFilePtrs.elf);
|
||||
|
||||
/* Create ELF Context */
|
||||
elf_context elf;
|
||||
|
||||
if ((result = elf_Init(&elf, elfFile))) goto finish;
|
||||
|
||||
if ((result = ImportPlainRegionFromElf(&elf, set))) goto finish;
|
||||
if ((result = CreateExeFsCode(&elf, set))) goto finish;
|
||||
|
||||
finish:
|
||||
switch (result) {
|
||||
case (0) :
|
||||
break;
|
||||
case (NOT_ELF_FILE) :
|
||||
fprintf(stderr, "[CODE ERROR] Not ELF File\n");
|
||||
break;
|
||||
case (NOT_CTR_ARM_ELF) :
|
||||
fprintf(stderr, "[CODE ERROR] Not CTR ARM ELF\n");
|
||||
break;
|
||||
case (NON_EXECUTABLE_ELF) :
|
||||
fprintf(stderr, "[CODE ERROR] Not Executeable ELF\n");
|
||||
break;
|
||||
case (NOT_FIND_TEXT_SEGMENT) :
|
||||
fprintf(stderr, "[CODE ERROR] Failed to retrieve text sections from ELF\n");
|
||||
break;
|
||||
case (NOT_FIND_DATA_SEGMENT) :
|
||||
fprintf(stderr, "[CODE ERROR] Failed to retrieve data sections from ELF\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[CODE ERROR] Failed to process ELF file (%d)\n", result);
|
||||
}
|
||||
|
||||
elf_Free(&elf);
|
||||
free(elfFile);
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
int BuildExeFsCode(ncch_settings *ncchset);
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 magic[4];
|
||||
u8 reserved0[4];
|
||||
u8 node0[4];
|
||||
u8 node1[4];
|
||||
u8 debugInfoOffset[4]; //s32
|
||||
u8 debugInfoSize[4]; //s32
|
||||
u8 reserved1[8];
|
||||
u8 uniqueIdMask[4];
|
||||
u8 uniqueIdPattern[4];
|
||||
u8 reserved2[0x18];
|
||||
u8 signPublicKey[0x100];
|
||||
u8 signPublicKeySign[0x100];
|
||||
u8 sign[0x100];
|
||||
u8 uniqueId[4];
|
||||
u8 size[4];
|
||||
u8 reserved3[8];
|
||||
u8 hashOffset[4];
|
||||
u8 numHash[4];
|
||||
u8 moduleIdOffset[4];
|
||||
u8 moduleIdSize[4];
|
||||
} crr_hdr;
|
||||
@@ -0,0 +1,210 @@
|
||||
#include "lib.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#include <mbedtls/aes.h>
|
||||
#include <mbedtls/rsa.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/sha1.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
|
||||
static const u8 RSA_PUB_EXP[0x3] = {0x01,0x00,0x01};
|
||||
static const int HASH_MAX_LEN = 0x20;
|
||||
|
||||
bool VerifySha256(void *data, u64 size, u8 hash[32])
|
||||
{
|
||||
u8 calchash[32];
|
||||
ShaCalc(data, size, calchash, CTR_SHA_256);
|
||||
return memcmp(hash,calchash,32) == 0;
|
||||
}
|
||||
|
||||
void ShaCalc(void *data, u64 size, u8 *hash, int mode)
|
||||
{
|
||||
switch(mode){
|
||||
case(CTR_SHA_1): mbedtls_sha1((u8*)data, size, hash); break;
|
||||
case(CTR_SHA_256): mbedtls_sha256((u8*)data, size, hash, 0); break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetAesCtrOffset(u8 *ctr, u64 offset)
|
||||
{
|
||||
u64_to_u8(ctr+8,u8_to_u64(ctr+8,BE)|align(offset,16)/16,BE);
|
||||
}
|
||||
|
||||
void AesCtrCrypt(u8 *key, u8 *ctr, u8 *input, u8 *output, u64 length, u64 offset)
|
||||
{
|
||||
u8 stream[16];
|
||||
mbedtls_aes_context aes;
|
||||
size_t nc_off = 0;
|
||||
|
||||
mbedtls_aes_init(&aes);
|
||||
mbedtls_aes_setkey_enc(&aes, key, 128);
|
||||
SetAesCtrOffset(ctr,offset);
|
||||
|
||||
mbedtls_aes_crypt_ctr(&aes, length, &nc_off, ctr, stream, input, output);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void AesCbcCrypt(u8 *key, u8 *iv, u8 *input, u8 *output, u64 length, u8 mode)
|
||||
{
|
||||
mbedtls_aes_context aes;
|
||||
mbedtls_aes_init(&aes);
|
||||
|
||||
switch(mode){
|
||||
case(ENC):
|
||||
mbedtls_aes_setkey_enc(&aes, key, 128);
|
||||
mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, length, iv, input, output);
|
||||
return;
|
||||
case(DEC):
|
||||
mbedtls_aes_setkey_dec(&aes, key, 128);
|
||||
mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, length, iv, input, output);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool RsaKeyInit(mbedtls_rsa_context* ctx, const u8 *modulus, const u8 *private_exp, const u8 *public_exp, u8 rsa_type)
|
||||
{
|
||||
// Sanity Check
|
||||
if(!ctx)
|
||||
return false;
|
||||
|
||||
mbedtls_rsa_init( ctx, MBEDTLS_RSA_PKCS_V15, 0 );
|
||||
|
||||
u16 n_size = 0;
|
||||
u16 d_size = 0;
|
||||
u16 e_size = 0;
|
||||
|
||||
switch(rsa_type){
|
||||
case RSA_2048:
|
||||
ctx->len = 0x100;
|
||||
n_size = 0x100;
|
||||
d_size = 0x100;
|
||||
e_size = 3;
|
||||
break;
|
||||
case RSA_4096:
|
||||
ctx->len = 0x200;
|
||||
n_size = 0x200;
|
||||
d_size = 0x200;
|
||||
e_size = 3;
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
int ret = mbedtls_rsa_import_raw(ctx, \
|
||||
modulus ? modulus : NULL, modulus ? n_size : 0, \
|
||||
NULL, 0, \
|
||||
NULL, 0, \
|
||||
private_exp ? private_exp : NULL, private_exp ? d_size : 0, \
|
||||
public_exp ? public_exp : NULL, public_exp ? e_size : 0);
|
||||
|
||||
if (ret != 0)
|
||||
goto clean;
|
||||
|
||||
return true;
|
||||
clean:
|
||||
mbedtls_rsa_free(ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
u8 GetRsaType(u32 sig_type)
|
||||
{
|
||||
switch(sig_type){
|
||||
case RSA_4096_SHA1:
|
||||
case RSA_4096_SHA256:
|
||||
return RSA_4096;
|
||||
case RSA_2048_SHA1:
|
||||
case RSA_2048_SHA256:
|
||||
return RSA_2048;
|
||||
}
|
||||
return INVALID_SIG_TYPE;
|
||||
}
|
||||
|
||||
u32 GetSigHashType(u32 sig_type)
|
||||
{
|
||||
switch(sig_type){
|
||||
case RSA_4096_SHA1:
|
||||
case RSA_2048_SHA1:
|
||||
case ECC_SHA1:
|
||||
return CTR_SHA_1;
|
||||
case RSA_4096_SHA256:
|
||||
case RSA_2048_SHA256:
|
||||
case ECC_SHA256:
|
||||
return CTR_SHA_256;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 GetSigHashLen(u32 sig_type)
|
||||
{
|
||||
switch(sig_type){
|
||||
case RSA_4096_SHA1:
|
||||
case RSA_2048_SHA1:
|
||||
case ECC_SHA1:
|
||||
return SHA_1_LEN;
|
||||
case RSA_4096_SHA256:
|
||||
case RSA_2048_SHA256:
|
||||
case ECC_SHA256:
|
||||
return SHA_256_LEN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbedtls_md_type_t getMdWrappedHashType(u32 sig_type)
|
||||
{
|
||||
mbedtls_md_type_t md_type = MBEDTLS_MD_NONE;
|
||||
|
||||
switch(sig_type){
|
||||
case RSA_4096_SHA1:
|
||||
case RSA_2048_SHA1:
|
||||
case ECC_SHA1:
|
||||
md_type = MBEDTLS_MD_SHA1;
|
||||
break;
|
||||
case RSA_4096_SHA256:
|
||||
case RSA_2048_SHA256:
|
||||
case ECC_SHA256:
|
||||
md_type = MBEDTLS_MD_SHA256;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return md_type;
|
||||
}
|
||||
|
||||
bool CalcHashForSign(void *data, u64 len, u8 *hash, u32 sig_type)
|
||||
{
|
||||
if(GetSigHashType(sig_type) == 0)
|
||||
return false;
|
||||
|
||||
ShaCalc(data, len, hash, GetSigHashType(sig_type));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int RsaSignVerify(void *data, u64 len, u8 *sign, u8 *mod, u8 *priv_exp, u32 sig_type, u8 rsa_mode)
|
||||
{
|
||||
int rsa_result = 0;
|
||||
mbedtls_rsa_context ctx;
|
||||
u8 hash[HASH_MAX_LEN];
|
||||
|
||||
if(!RsaKeyInit(&ctx, mod, priv_exp, RSA_PUB_EXP, GetRsaType(sig_type)))
|
||||
return -1;
|
||||
|
||||
if(!CalcHashForSign(data, len, hash, sig_type))
|
||||
return -1;
|
||||
|
||||
if(rsa_mode == CTR_RSA_VERIFY)
|
||||
{
|
||||
rsa_result = mbedtls_rsa_rsassa_pkcs1_v15_verify(&ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, getMdWrappedHashType(sig_type), GetSigHashLen(sig_type), hash, sign);
|
||||
}
|
||||
else // CTR_RSA_SIGN
|
||||
{
|
||||
rsa_result = mbedtls_rsa_rsassa_pkcs1_v15_sign(&ctx, NULL, NULL, MBEDTLS_RSA_PRIVATE, getMdWrappedHashType(sig_type), GetSigHashLen(sig_type), hash, sign);
|
||||
}
|
||||
|
||||
|
||||
mbedtls_rsa_free(&ctx);
|
||||
return rsa_result;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RSA_4096_SHA1 = 0x00010000,
|
||||
RSA_2048_SHA1 = 0x00010001,
|
||||
ECC_SHA1 = 0x00010002,
|
||||
RSA_4096_SHA256 = 0x00010003,
|
||||
RSA_2048_SHA256 = 0x00010004,
|
||||
ECC_SHA256 = 0x00010005
|
||||
} ctr_sig_types;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CTR_RSA_VERIFY,
|
||||
CTR_RSA_SIGN,
|
||||
} ctr_rsa_mode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RSA_4096,
|
||||
RSA_2048,
|
||||
ECC,
|
||||
INVALID_SIG_TYPE,
|
||||
} sig_types;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CTR_SHA_1,
|
||||
CTR_SHA_256,
|
||||
} ctr_sha_modes;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SHA_1_LEN = 0x14,
|
||||
SHA_256_LEN = 0x20,
|
||||
} sha_hash_len;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RSA_4096_PUBK = 0,
|
||||
RSA_2048_PUBK,
|
||||
ECC_PUBK
|
||||
} pubk_types;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ENC,
|
||||
DEC
|
||||
} aes_mode;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// SHA
|
||||
bool VerifySha256(void *data, u64 size, u8 hash[32]);
|
||||
void ShaCalc(void *data, u64 size, u8 *hash, int mode);
|
||||
// AES
|
||||
void AesCtrCrypt(u8 *key, u8 *ctr, u8 *input, u8 *output, u64 length, u64 offset);
|
||||
void AesCbcCrypt(u8 *key, u8 *iv, u8 *input, u8 *output, u64 length, u8 mode);
|
||||
// RSA
|
||||
int RsaSignVerify(void *data, u64 len, u8 *sign, u8 *mod, u8 *priv_exp, u32 sig_type, u8 rsa_mode);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "lib.h"
|
||||
|
||||
u32 GetCtrBlockSize(u8 flag)
|
||||
{
|
||||
return 1 << (flag + 9);
|
||||
}
|
||||
|
||||
u8 GetCtrBlockSizeFlag(u32 size)
|
||||
{
|
||||
u8 ret = 0;
|
||||
for(u32 tmp = size; tmp > 0x200; tmp = tmp >> 1)
|
||||
ret++;
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
u32 GetCtrBlockSize(u8 flag);
|
||||
u8 GetCtrBlockSizeFlag(u32 size);
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
enum SdkAppTypes {
|
||||
desc_NotSpecified,
|
||||
desc_Application,
|
||||
desc_DlpChild,
|
||||
desc_Demo,
|
||||
desc_EcApplication, // intergrated in (Ext)Application since SDK 7
|
||||
desc_ExtApplication, // Snake equivalent of desc_Application (128MB/804MHz/L2 Cache)
|
||||
desc_ExtDlpChild, // Snake equivalent of desc_DlpChild (128MB/804MHz/L2 Cache)
|
||||
desc_ExtDemo // Snake equivalent of desc_Demo (128MB/804MHz/L2 Cache)
|
||||
};
|
||||
|
||||
typedef struct CtrSdkDepList {
|
||||
uint32_t fw_minor;
|
||||
uint8_t dependency[0x180];
|
||||
} CtrSdkDepList;
|
||||
|
||||
typedef struct CtrSdkDesc {
|
||||
uint32_t type;
|
||||
uint32_t fw_minor;
|
||||
uint8_t exheader_desc[0x200];
|
||||
uint8_t signed_desc[0x200];
|
||||
} CtrSdkDesc;
|
||||
|
||||
typedef struct CtrSdkDescSignData {
|
||||
uint32_t type;
|
||||
uint32_t fw_minor;
|
||||
uint8_t modulus[0x100];
|
||||
uint8_t priv_exponent[0x100];
|
||||
uint8_t access_desc_signature[0x100];
|
||||
} CtrSdkDescSignData;
|
||||
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#include "desc.h"
|
||||
|
||||
static const CtrSdkDescSignData kDevDescSignData[] =
|
||||
{
|
||||
/* CTR_SDK 1 (1.2.0) */
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 27,
|
||||
.modulus = { 0x9B, 0x82, 0x9C, 0x19, 0x01, 0x73, 0x23, 0x50, 0x89, 0xE3, 0x0B, 0xC8, 0x8F, 0xFB, 0xA5, 0xE4, 0xFD, 0x44, 0xAE, 0x49, 0x32, 0xC7, 0xEF, 0x0A, 0x7E, 0x93, 0x95, 0xBA, 0xA2, 0x48, 0x4D, 0x8E, 0x18, 0x82, 0x34, 0x66, 0xFE, 0xDA, 0x7A, 0x45, 0x4A, 0x7D, 0xD5, 0x3C, 0xC6, 0x5C, 0xE0, 0x71, 0xFC, 0xD0, 0x82, 0xCC, 0xB2, 0xCF, 0x77, 0x0E, 0xAD, 0xCD, 0xD2, 0xAC, 0x1D, 0x66, 0x1B, 0xC1, 0xEA, 0xAC, 0x39, 0x96, 0x2C, 0x52, 0xDE, 0xFF, 0xF2, 0x74, 0xF6, 0xC5, 0xCA, 0x99, 0x31, 0x95, 0x13, 0xBB, 0x3F, 0xED, 0x30, 0xAE, 0x0A, 0xD3, 0x86, 0x0D, 0x0B, 0xF5, 0x56, 0x7D, 0x33, 0xBA, 0xA1, 0x39, 0xA2, 0xF5, 0xB6, 0x47, 0x78, 0x1F, 0xFD, 0x04, 0xA3, 0x49, 0xA9, 0x10, 0xD3, 0x41, 0x2E, 0x92, 0x7D, 0xE1, 0xA4, 0xA8, 0x02, 0x18, 0x01, 0x2C, 0xC2, 0x61, 0xB1, 0xAC, 0xCB, 0xB3, 0x7A, 0x64, 0xB1, 0xC3, 0xE6, 0x3B, 0x50, 0xAD, 0xDD, 0x55, 0xAB, 0x28, 0xDA, 0x59, 0xE7, 0x57, 0x6A, 0x76, 0x4F, 0x6B, 0x08, 0xD1, 0x61, 0x7D, 0x28, 0xD5, 0x88, 0x7B, 0x8E, 0x80, 0x78, 0xF3, 0xFF, 0x50, 0x00, 0xBD, 0x73, 0xFB, 0x62, 0xB3, 0xCA, 0xA8, 0x05, 0x48, 0xE6, 0xE6, 0x71, 0xB5, 0xAC, 0xDA, 0xE9, 0xC6, 0x1F, 0x9B, 0x72, 0x98, 0x2E, 0xFF, 0xB2, 0x9C, 0x36, 0x9F, 0x7E, 0x7D, 0x25, 0x65, 0x6F, 0xB0, 0x60, 0xB1, 0xB5, 0x5F, 0xCF, 0x74, 0x29, 0x91, 0x9D, 0xAB, 0x84, 0x97, 0x1A, 0x27, 0x5D, 0x69, 0x49, 0x16, 0xF8, 0x77, 0x31, 0x26, 0x3E, 0x6F, 0x97, 0x41, 0x4A, 0x26, 0xFD, 0x5B, 0xAB, 0x65, 0x77, 0x45, 0x1C, 0x76, 0x15, 0xDC, 0x1A, 0x63, 0x0F, 0x51, 0x2D, 0xA0, 0x07, 0x6E, 0xE5, 0x29, 0xD3, 0x37, 0x4B, 0xE5, 0x7F, 0xBB, 0x23, 0xD0, 0x2B, 0xB9, 0x76, 0x1F },
|
||||
.priv_exponent = { 0x66, 0x9F, 0xB5, 0xC5, 0xA6, 0xB8, 0x45, 0xD8, 0xD3, 0x75, 0xFB, 0x03, 0xBB, 0x48, 0xF5, 0x7C, 0x7D, 0x4B, 0x02, 0xBD, 0x19, 0x7E, 0xE9, 0x98, 0x02, 0x5A, 0x00, 0xD8, 0x6E, 0x59, 0xCA, 0x9C, 0x78, 0x3E, 0x0C, 0xB8, 0xDF, 0x7C, 0x6C, 0x6E, 0x27, 0xAF, 0x8C, 0xB6, 0x13, 0xAD, 0x9D, 0x0C, 0x7C, 0x2B, 0x59, 0xF6, 0x1E, 0x16, 0x5D, 0x5A, 0x59, 0x86, 0x57, 0x7D, 0xEF, 0xD4, 0xBF, 0x82, 0xA4, 0x0C, 0x4D, 0xE0, 0x75, 0x95, 0xA6, 0xC6, 0x3F, 0x49, 0xC2, 0xC4, 0x5A, 0x63, 0xE8, 0x5D, 0x99, 0xEC, 0xDB, 0x4D, 0xFA, 0xEF, 0x10, 0x03, 0xF1, 0x15, 0xD1, 0x0B, 0x71, 0xAD, 0x24, 0x23, 0x08, 0x5C, 0x91, 0xD7, 0x17, 0x18, 0x69, 0x04, 0xAB, 0x23, 0x91, 0x62, 0x7D, 0xE8, 0xB5, 0x90, 0xF1, 0x5C, 0x09, 0x28, 0x8C, 0x51, 0xB7, 0x38, 0x02, 0x26, 0x78, 0x8C, 0xA2, 0x05, 0x07, 0x53, 0x7D, 0x99, 0x46, 0xFD, 0x12, 0x77, 0x32, 0x0E, 0xA8, 0x54, 0xE3, 0x32, 0x0E, 0x93, 0x05, 0x10, 0xFA, 0x59, 0x7A, 0x5D, 0x2E, 0xDE, 0x32, 0xE8, 0xE9, 0xF0, 0x27, 0x4E, 0x08, 0x83, 0x08, 0xD4, 0x92, 0x58, 0x4D, 0x6D, 0x34, 0x9F, 0xD9, 0xAF, 0xA9, 0x01, 0x62, 0xB5, 0x1A, 0x1D, 0x7E, 0x8D, 0xBB, 0x8A, 0x58, 0xBA, 0xFF, 0xB4, 0xD3, 0x75, 0xF3, 0x44, 0xE7, 0x13, 0x05, 0xC6, 0xC5, 0xA4, 0xD2, 0x6B, 0x18, 0x31, 0x9F, 0xBE, 0x42, 0x45, 0x82, 0x2E, 0x47, 0x9B, 0x26, 0x73, 0x28, 0xD7, 0x9A, 0x64, 0xA6, 0x3D, 0x38, 0x9C, 0x11, 0x36, 0x01, 0x5B, 0x82, 0x2F, 0x7E, 0xA8, 0xC4, 0x82, 0x15, 0x6C, 0x0B, 0xBA, 0x1C, 0x58, 0xF5, 0x81, 0xF9, 0x45, 0xA9, 0xC6, 0x05, 0x6A, 0x2C, 0xA6, 0xCF, 0xF5, 0xDF, 0xEB, 0xBB, 0xC0, 0x92, 0xE3, 0xA6, 0x9D, 0x23, 0x09, 0x09, 0x0E, 0x98, 0x39 },
|
||||
.access_desc_signature = { 0x05, 0x90, 0xAF, 0x65, 0x16, 0x9F, 0x18, 0x2C, 0x17, 0x78, 0x9F, 0xDF, 0xB6, 0x37, 0xCF, 0x26, 0x9B, 0x1B, 0x75, 0x51, 0xB8, 0x57, 0xA3, 0x8F, 0xD7, 0x93, 0x19, 0x61, 0x81, 0x0D, 0x3D, 0xBC, 0x36, 0x50, 0x53, 0xDA, 0x7D, 0xA9, 0x7F, 0xAA, 0x3E, 0x51, 0x2C, 0x75, 0xA1, 0xB9, 0xB1, 0x56, 0xEB, 0x2A, 0x46, 0x21, 0xEC, 0x4F, 0xA7, 0x0C, 0xA1, 0xA8, 0xFD, 0xEE, 0xA3, 0x4A, 0xFD, 0x54, 0xB0, 0x3A, 0x49, 0x5C, 0x8F, 0x8D, 0xB2, 0xBC, 0x32, 0x50, 0x7E, 0x2C, 0x50, 0xD2, 0x1A, 0x6B, 0x61, 0xCB, 0x2A, 0xC9, 0x7E, 0x6E, 0x6A, 0xC8, 0xD6, 0x9B, 0x21, 0xE7, 0x3B, 0xB8, 0x39, 0x1C, 0xD7, 0xEB, 0x69, 0x35, 0xF5, 0xBC, 0xB5, 0x23, 0x54, 0x81, 0x4F, 0x73, 0xAB, 0x9C, 0x55, 0xF0, 0x04, 0x0B, 0x4A, 0xEA, 0x54, 0x08, 0xBF, 0x36, 0x28, 0x12, 0x5E, 0x44, 0x41, 0xF5, 0x3D, 0xFE, 0xA7, 0x6B, 0x35, 0xF2, 0x9A, 0xF2, 0x88, 0xCD, 0xD6, 0x2E, 0x7B, 0xF3, 0xF5, 0x0D, 0x06, 0x2E, 0x13, 0x4F, 0x78, 0xEE, 0x27, 0xAB, 0x31, 0x06, 0x62, 0xE9, 0xB2, 0x3E, 0xC6, 0x99, 0xD7, 0xA9, 0xCC, 0x21, 0x70, 0xD7, 0xCD, 0x9F, 0x03, 0x66, 0x91, 0x7E, 0xBD, 0x3E, 0x83, 0xC4, 0xFF, 0xC9, 0xAA, 0x7E, 0x27, 0xAE, 0x5C, 0x37, 0x7D, 0x93, 0x57, 0x60, 0xB9, 0x0B, 0x71, 0x43, 0x8A, 0x2F, 0x43, 0x50, 0x94, 0xF8, 0x0D, 0x40, 0xCC, 0x64, 0x16, 0x09, 0x70, 0xCD, 0x03, 0xCA, 0x95, 0x30, 0x20, 0xE2, 0x85, 0x2F, 0x2A, 0xCF, 0x65, 0xAA, 0xE9, 0xCF, 0x1F, 0x57, 0xC1, 0x8F, 0xD5, 0x46, 0x51, 0x5A, 0x99, 0x60, 0x65, 0x93, 0xA9, 0xBB, 0xEA, 0x5F, 0xA0, 0x47, 0xD7, 0x11, 0x04, 0xC7, 0xB4, 0x82, 0x66, 0x24, 0x17, 0x17, 0x5E, 0x9D, 0xC8, 0x50, 0x80, 0x63, 0x28, 0xB3, 0xF8, 0xE3 }
|
||||
},
|
||||
{
|
||||
.type = desc_DlpChild,
|
||||
.fw_minor = 27,
|
||||
.modulus = { 0xD9, 0xF0, 0xC9, 0x35, 0x1E, 0x55, 0xD8, 0x7E, 0x96, 0x53, 0x33, 0x34, 0xBB, 0x8A, 0xAE, 0x03, 0x92, 0x35, 0xE2, 0x05, 0x58, 0x7C, 0xCC, 0x08, 0xB2, 0xDF, 0x43, 0x41, 0xB7, 0x7A, 0xB5, 0x29, 0xEE, 0x4E, 0xF3, 0xC7, 0x35, 0x3B, 0x7E, 0xC5, 0xEE, 0x74, 0xF0, 0xAA, 0x7E, 0x60, 0xF1, 0x28, 0x35, 0x17, 0xD6, 0xC9, 0x9A, 0xF2, 0x84, 0xFE, 0xC8, 0x93, 0x86, 0xF7, 0xA7, 0x36, 0xA6, 0xB0, 0x28, 0xDC, 0xE8, 0x38, 0x0B, 0x54, 0x42, 0x8D, 0x4E, 0x4B, 0x55, 0x0F, 0x4A, 0x0D, 0x72, 0xA0, 0x23, 0xC9, 0x68, 0x22, 0x37, 0x31, 0x88, 0x2C, 0x05, 0x49, 0x86, 0x80, 0x9A, 0xFC, 0x1D, 0x02, 0xE3, 0x20, 0x15, 0x0C, 0x7E, 0x28, 0x40, 0x57, 0xEF, 0xA7, 0xBC, 0xAA, 0xC5, 0xD6, 0xD7, 0x6F, 0xF9, 0x26, 0x9A, 0x32, 0xB2, 0x9E, 0x10, 0x5F, 0x93, 0xE6, 0xB2, 0xC6, 0xB2, 0x62, 0x34, 0x6A, 0xB0, 0xD9, 0x71, 0x3B, 0x0F, 0x34, 0x6C, 0xB1, 0xFE, 0x3A, 0x39, 0xDE, 0x3D, 0x6A, 0xCB, 0x32, 0x95, 0xFA, 0x18, 0x4F, 0xF4, 0xEB, 0x5F, 0x20, 0xE4, 0xEF, 0x64, 0xC5, 0x06, 0x27, 0xC3, 0x44, 0x2A, 0x39, 0x35, 0xD8, 0x00, 0xDF, 0x00, 0xAD, 0xC4, 0x98, 0x06, 0x52, 0xD8, 0x4A, 0xC5, 0x2A, 0x7F, 0x77, 0x50, 0x62, 0x7E, 0x05, 0x3E, 0x8C, 0x28, 0x0A, 0x26, 0xD2, 0x6C, 0x9B, 0x27, 0x65, 0xE9, 0x77, 0x68, 0xE9, 0xE6, 0xAA, 0xBA, 0xF5, 0x85, 0xFC, 0x75, 0x07, 0x84, 0xB2, 0xCA, 0x35, 0x85, 0x52, 0x10, 0x08, 0xEF, 0x85, 0xD3, 0x70, 0x17, 0x31, 0xE1, 0x44, 0xF6, 0x34, 0xDF, 0x7C, 0x42, 0xF7, 0x74, 0xAA, 0xFC, 0xC3, 0xE4, 0x84, 0x2D, 0xBF, 0x15, 0x1E, 0x84, 0x00, 0xE3, 0x80, 0xD7, 0x89, 0x56, 0xEE, 0x60, 0x09, 0x1F, 0xD3, 0xBF, 0xBF, 0x50, 0x8F, 0xA3, 0x0C, 0x72, 0x3F },
|
||||
.priv_exponent = { 0x10, 0x19, 0x3A, 0x33, 0xA3, 0x47, 0x02, 0x13, 0xEF, 0xB4, 0xBB, 0x9E, 0x94, 0x8F, 0xDC, 0xE4, 0xC4, 0xA3, 0x18, 0x4B, 0xFE, 0xCA, 0x51, 0x23, 0xFF, 0x5A, 0x80, 0x94, 0x55, 0x22, 0x4A, 0x49, 0x8B, 0xA1, 0xE7, 0x5D, 0xFA, 0xAF, 0xA7, 0x60, 0xA5, 0x89, 0x9B, 0xD1, 0x6C, 0x3E, 0x6A, 0xF1, 0xE6, 0x62, 0x19, 0x6A, 0x90, 0xF8, 0x83, 0x1C, 0x72, 0xE2, 0x7A, 0xE0, 0xC6, 0x48, 0x42, 0x2D, 0xD7, 0x06, 0xE2, 0x5C, 0x69, 0x71, 0xD2, 0xEC, 0xAF, 0x30, 0xDF, 0x5A, 0x9E, 0xC4, 0xB9, 0x87, 0xDC, 0xBC, 0xDE, 0xE5, 0x50, 0x20, 0x67, 0x87, 0xA0, 0xE8, 0x5A, 0x78, 0x1B, 0x7A, 0xAE, 0x05, 0xED, 0x93, 0x0C, 0x1A, 0xFD, 0x22, 0xAA, 0x06, 0x14, 0xDC, 0xD6, 0x11, 0xE3, 0x45, 0x48, 0x6A, 0xAC, 0x03, 0xCE, 0xF6, 0x19, 0xBD, 0x95, 0x46, 0x0A, 0x1D, 0xCB, 0x6C, 0xE3, 0xF6, 0x5F, 0x1A, 0xB3, 0x81, 0xC7, 0xE2, 0xAB, 0xFE, 0xEF, 0xFB, 0xEC, 0xFE, 0x88, 0x36, 0x26, 0x60, 0x47, 0x43, 0x78, 0x36, 0xA7, 0xC8, 0xC9, 0x40, 0x98, 0x2E, 0xF2, 0x7E, 0xE4, 0x0D, 0x6C, 0x45, 0x88, 0x2A, 0x32, 0x9B, 0xA2, 0x7C, 0x39, 0x20, 0xAA, 0x6B, 0x64, 0x35, 0xC6, 0xA9, 0x20, 0x71, 0x4A, 0x78, 0x6E, 0x55, 0x3C, 0x9B, 0xEA, 0x10, 0x73, 0xBB, 0xA7, 0xD8, 0xFE, 0x69, 0x42, 0xB8, 0xE7, 0xA1, 0xE5, 0xDF, 0x8A, 0xDE, 0x4C, 0x2B, 0x3A, 0x92, 0xB8, 0x3E, 0x5E, 0x2C, 0x29, 0x0D, 0xC1, 0x3D, 0x10, 0x65, 0x1E, 0xF1, 0x95, 0xE5, 0xF6, 0x45, 0x15, 0xBF, 0xE2, 0x30, 0xA6, 0x70, 0x19, 0xA4, 0x11, 0x57, 0x12, 0x1C, 0x81, 0x4B, 0x54, 0x04, 0xBE, 0x67, 0xF5, 0x00, 0x22, 0x06, 0xDA, 0x6B, 0xCE, 0x23, 0x3F, 0x86, 0xE4, 0x70, 0x6A, 0xD1, 0x3E, 0xE5, 0x74, 0x44, 0x86, 0xDA, 0xBE, 0x79 },
|
||||
.access_desc_signature = { 0x10, 0x19, 0x3A, 0x33, 0xA3, 0x47, 0x02, 0x13, 0xEF, 0xB4, 0xBB, 0x9E, 0x94, 0x8F, 0xDC, 0xE4, 0xC4, 0xA3, 0x18, 0x4B, 0xFE, 0xCA, 0x51, 0x23, 0xFF, 0x5A, 0x80, 0x94, 0x55, 0x22, 0x4A, 0x49, 0x8B, 0xA1, 0xE7, 0x5D, 0xFA, 0xAF, 0xA7, 0x60, 0xA5, 0x89, 0x9B, 0xD1, 0x6C, 0x3E, 0x6A, 0xF1, 0xE6, 0x62, 0x19, 0x6A, 0x90, 0xF8, 0x83, 0x1C, 0x72, 0xE2, 0x7A, 0xE0, 0xC6, 0x48, 0x42, 0x2D, 0xD7, 0x06, 0xE2, 0x5C, 0x69, 0x71, 0xD2, 0xEC, 0xAF, 0x30, 0xDF, 0x5A, 0x9E, 0xC4, 0xB9, 0x87, 0xDC, 0xBC, 0xDE, 0xE5, 0x50, 0x20, 0x67, 0x87, 0xA0, 0xE8, 0x5A, 0x78, 0x1B, 0x7A, 0xAE, 0x05, 0xED, 0x93, 0x0C, 0x1A, 0xFD, 0x22, 0xAA, 0x06, 0x14, 0xDC, 0xD6, 0x11, 0xE3, 0x45, 0x48, 0x6A, 0xAC, 0x03, 0xCE, 0xF6, 0x19, 0xBD, 0x95, 0x46, 0x0A, 0x1D, 0xCB, 0x6C, 0xE3, 0xF6, 0x5F, 0x1A, 0xB3, 0x81, 0xC7, 0xE2, 0xAB, 0xFE, 0xEF, 0xFB, 0xEC, 0xFE, 0x88, 0x36, 0x26, 0x60, 0x47, 0x43, 0x78, 0x36, 0xA7, 0xC8, 0xC9, 0x40, 0x98, 0x2E, 0xF2, 0x7E, 0xE4, 0x0D, 0x6C, 0x45, 0x88, 0x2A, 0x32, 0x9B, 0xA2, 0x7C, 0x39, 0x20, 0xAA, 0x6B, 0x64, 0x35, 0xC6, 0xA9, 0x20, 0x71, 0x4A, 0x78, 0x6E, 0x55, 0x3C, 0x9B, 0xEA, 0x10, 0x73, 0xBB, 0xA7, 0xD8, 0xFE, 0x69, 0x42, 0xB8, 0xE7, 0xA1, 0xE5, 0xDF, 0x8A, 0xDE, 0x4C, 0x2B, 0x3A, 0x92, 0xB8, 0x3E, 0x5E, 0x2C, 0x29, 0x0D, 0xC1, 0x3D, 0x10, 0x65, 0x1E, 0xF1, 0x95, 0xE5, 0xF6, 0x45, 0x15, 0xBF, 0xE2, 0x30, 0xA6, 0x70, 0x19, 0xA4, 0x11, 0x57, 0x12, 0x1C, 0x81, 0x4B, 0x54, 0x04, 0xBE, 0x67, 0xF5, 0x00, 0x22, 0x06, 0xDA, 0x6B, 0xCE, 0x23, 0x3F, 0x86, 0xE4, 0x70, 0x6A, 0xD1, 0x3E, 0xE5, 0x74, 0x44, 0x86, 0xDA, 0xBE, 0x79 }
|
||||
},
|
||||
/* CTR_SDK 2 (2.3.4) */
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 29,
|
||||
.modulus = { 0xE9, 0x45, 0xF0, 0xC6, 0x96, 0xD5, 0x6F, 0x7E, 0xAE, 0x03, 0x92, 0x2E, 0xEA, 0xCB, 0xFD, 0xEA, 0xA4, 0x7A, 0x9F, 0x12, 0xDA, 0x4C, 0x10, 0x0A, 0xBE, 0x08, 0x9D, 0x87, 0xE0, 0x14, 0xAC, 0x7F, 0x39, 0xD2, 0xFE, 0x9D, 0x88, 0xB2, 0x81, 0xF6, 0x1A, 0x9E, 0x15, 0x57, 0xD4, 0xE2, 0x31, 0x08, 0x07, 0xEC, 0x4F, 0x10, 0x00, 0xDE, 0xEF, 0x8B, 0x6F, 0xCF, 0x84, 0xE7, 0x3B, 0x41, 0x08, 0x64, 0x3B, 0x1C, 0x00, 0x7C, 0x73, 0xBB, 0x59, 0x4D, 0xD8, 0xD6, 0xE7, 0x7B, 0xBE, 0xDD, 0x50, 0x98, 0xA1, 0x1A, 0xD5, 0xAA, 0x37, 0x69, 0xB8, 0x25, 0xCB, 0x7B, 0x03, 0x00, 0x90, 0x25, 0xF3, 0x7E, 0x9A, 0x0F, 0xA3, 0xAA, 0xC4, 0xB9, 0x3B, 0x3A, 0x18, 0x2B, 0xBC, 0x9C, 0x11, 0x04, 0x92, 0x16, 0x6E, 0xC3, 0xFA, 0x01, 0xD3, 0x00, 0x02, 0xF3, 0x2E, 0xD5, 0x60, 0xA8, 0xAF, 0xAB, 0xEE, 0x2F, 0x9D, 0x30, 0x3E, 0x0E, 0xDC, 0xB8, 0xEC, 0x87, 0x9E, 0x4A, 0xA9, 0x01, 0x34, 0x69, 0x2C, 0x4C, 0x34, 0xB7, 0x7D, 0xB9, 0x7A, 0x17, 0x74, 0x31, 0xB0, 0x29, 0xC4, 0x7D, 0x27, 0x1F, 0xBA, 0xBA, 0x3F, 0x5B, 0x62, 0xF6, 0x90, 0xB8, 0x37, 0x33, 0xFC, 0x73, 0xD6, 0x19, 0x11, 0xCA, 0x83, 0x2A, 0x58, 0x62, 0x9C, 0xB1, 0x83, 0x43, 0x1D, 0x2C, 0x00, 0xA2, 0xE5, 0x87, 0x97, 0x12, 0x63, 0x31, 0x83, 0x0E, 0xB1, 0x1E, 0x69, 0x99, 0x02, 0xAF, 0xDF, 0xFF, 0x0F, 0xA9, 0x7C, 0x1B, 0x33, 0x9E, 0xFF, 0x9C, 0x14, 0x19, 0xA6, 0xCA, 0xFD, 0xB9, 0x17, 0xE0, 0x22, 0xCF, 0xB5, 0x00, 0x77, 0x2E, 0x31, 0xAD, 0xF7, 0xE5, 0xAD, 0x98, 0x14, 0xDF, 0x19, 0xF0, 0xC9, 0xBE, 0x37, 0xF6, 0xF0, 0x23, 0x66, 0xCF, 0x34, 0xE3, 0xD5, 0x8F, 0xD4, 0x07, 0xBA, 0x06, 0x56, 0x00, 0x66, 0x9A, 0xEB, 0x93 },
|
||||
.priv_exponent = { 0xBC, 0x49, 0x29, 0xB9, 0x01, 0x52, 0x31, 0x76, 0x4C, 0xBA, 0xB1, 0x29, 0x91, 0x77, 0x29, 0xF2, 0x54, 0xE4, 0x6C, 0xB5, 0x68, 0xE1, 0xF0, 0x28, 0xDB, 0x8E, 0x54, 0xA8, 0xB1, 0xA3, 0xBE, 0x3F, 0xCA, 0xCA, 0x95, 0x9D, 0x4E, 0x12, 0xD7, 0x77, 0x6F, 0xB0, 0x9D, 0x85, 0x91, 0x5D, 0x29, 0x3A, 0x54, 0x3A, 0xD6, 0xEE, 0x11, 0xE5, 0xDF, 0xEF, 0xEA, 0x45, 0xD3, 0xFE, 0x58, 0x03, 0x7B, 0xE4, 0x7B, 0x19, 0x75, 0x02, 0xFE, 0xDE, 0xFF, 0x8C, 0x28, 0x33, 0xFE, 0x10, 0x11, 0xD4, 0xCD, 0x13, 0x05, 0x26, 0x85, 0xC3, 0xA8, 0x8A, 0x7A, 0x8A, 0x77, 0x1D, 0x49, 0x25, 0x11, 0x34, 0xB0, 0xBF, 0x45, 0x56, 0xCE, 0x42, 0x2E, 0x1B, 0x5C, 0xC4, 0xDD, 0x71, 0xA0, 0x01, 0x50, 0x73, 0x21, 0xFF, 0x5D, 0x54, 0x6D, 0xDD, 0x3F, 0x14, 0x49, 0x4D, 0x44, 0x46, 0x12, 0x88, 0xD5, 0x92, 0xAE, 0xE2, 0xD0, 0xF6, 0x2C, 0x10, 0xD5, 0x67, 0x61, 0x87, 0x7F, 0x2A, 0x17, 0x9D, 0x4F, 0xC6, 0x79, 0xC3, 0xAF, 0x4D, 0x6F, 0xFB, 0x0F, 0x3B, 0x48, 0x5D, 0x46, 0x9A, 0xE8, 0x53, 0xB7, 0xC5, 0x69, 0xEC, 0x31, 0x25, 0xD1, 0xDC, 0x93, 0xAB, 0x2E, 0x53, 0x3B, 0x8E, 0x96, 0x27, 0x59, 0xD4, 0xF7, 0xB3, 0xAB, 0x51, 0x59, 0xAE, 0x6E, 0x26, 0x4F, 0xC2, 0x95, 0xCE, 0x42, 0xC6, 0xAF, 0x46, 0xC6, 0x2E, 0x32, 0x09, 0x7B, 0xAF, 0x67, 0x4E, 0x57, 0xC8, 0x93, 0x5F, 0x8C, 0xD5, 0x66, 0x7B, 0xCC, 0xE9, 0xBE, 0x86, 0xB9, 0xBB, 0xD0, 0xC8, 0xD2, 0xDC, 0x5F, 0x95, 0x83, 0x28, 0x55, 0x21, 0x1E, 0xEE, 0xCF, 0x23, 0xB7, 0x6D, 0xE0, 0x9A, 0x87, 0x99, 0xFB, 0x82, 0x50, 0xD0, 0x2D, 0xC4, 0xFB, 0xA0, 0x11, 0x2F, 0xDD, 0x05, 0x7E, 0x1C, 0xE3, 0xFB, 0x98, 0x69, 0xD4, 0x49, 0x2F, 0x0D, 0xF6, 0x61 },
|
||||
.access_desc_signature = { 0x62, 0xFE, 0xD9, 0x12, 0x3D, 0x99, 0x53, 0xC4, 0x20, 0x25, 0xDE, 0x59, 0xEA, 0x6E, 0xF3, 0x16, 0x5B, 0x36, 0xBA, 0x1C, 0xB3, 0xB5, 0x48, 0x37, 0xD2, 0xA4, 0x04, 0xE5, 0x14, 0xC6, 0xE7, 0x22, 0x14, 0x40, 0x6F, 0x92, 0x6A, 0x9B, 0xDF, 0xDE, 0xFA, 0xCE, 0x3C, 0xBB, 0x4B, 0xC4, 0x66, 0xA8, 0x86, 0x58, 0xAC, 0xEB, 0x2F, 0xB7, 0xA3, 0xEC, 0xEA, 0x31, 0x23, 0x61, 0xF6, 0x72, 0x1E, 0x26, 0x8A, 0x1D, 0x68, 0x2A, 0x2A, 0x21, 0x5A, 0xA2, 0x6A, 0xBD, 0xCE, 0xC0, 0x19, 0x08, 0x61, 0x64, 0xB3, 0xF6, 0x90, 0xB1, 0x34, 0xF8, 0x50, 0x6F, 0x83, 0xB6, 0x8D, 0x35, 0x12, 0x7F, 0x9C, 0x7B, 0x6E, 0x3C, 0x4E, 0xD1, 0xFD, 0xC3, 0x30, 0xD2, 0xE8, 0x7E, 0x15, 0x1F, 0xAD, 0xDB, 0x1D, 0x92, 0xDA, 0x8C, 0x4E, 0xE9, 0x84, 0x83, 0xFF, 0x1A, 0x09, 0x77, 0x05, 0x5A, 0xCF, 0x5C, 0x8B, 0x4F, 0x68, 0x36, 0xC8, 0xDA, 0x5B, 0x1A, 0x5A, 0x49, 0xF9, 0xA1, 0xF2, 0xC8, 0x02, 0xFD, 0x69, 0x1F, 0x1D, 0xB3, 0xE8, 0xF8, 0xE1, 0x6B, 0x15, 0x9A, 0x5E, 0x41, 0x84, 0x06, 0x1F, 0x2A, 0xB3, 0xB2, 0xA1, 0xDC, 0x63, 0x81, 0xB3, 0x6B, 0x4B, 0x21, 0x67, 0x19, 0x82, 0x52, 0xFE, 0x75, 0x96, 0xA1, 0xDF, 0x02, 0xD4, 0x07, 0x1F, 0x1B, 0x88, 0x12, 0x5A, 0x76, 0x54, 0xC4, 0x06, 0x2D, 0xB1, 0xAA, 0x41, 0x3C, 0x9F, 0x43, 0xA2, 0x75, 0x20, 0x39, 0xB6, 0x06, 0xF9, 0x9C, 0xFC, 0x00, 0xC5, 0xBC, 0x84, 0x13, 0x80, 0xE4, 0x10, 0x1A, 0xCD, 0x95, 0xBB, 0xF2, 0xDC, 0x57, 0x7B, 0xBA, 0x87, 0x05, 0x0B, 0x96, 0xC1, 0xCD, 0x60, 0xC7, 0x10, 0x44, 0x78, 0x0E, 0x0F, 0x2F, 0x91, 0x54, 0x6C, 0xDE, 0xB8, 0x14, 0x46, 0xF3, 0x9C, 0xAC, 0x7B, 0xAA, 0xE7, 0x1B, 0x52, 0xD6, 0xBE, 0x71, 0x97, 0x22 }
|
||||
},
|
||||
{
|
||||
.type = desc_DlpChild,
|
||||
.fw_minor = 29,
|
||||
.modulus = { 0xB9, 0xDE, 0x3D, 0xC0, 0x55, 0xB9, 0xCC, 0x3F, 0x55, 0xE0, 0x61, 0x1D, 0x6F, 0xCF, 0x3E, 0x7F, 0xE2, 0xF7, 0xF5, 0xAD, 0x5C, 0x02, 0x7F, 0x17, 0x5B, 0x44, 0x2F, 0x2D, 0xDC, 0xD4, 0xA6, 0x63, 0xD2, 0xA7, 0x82, 0xD3, 0x00, 0x77, 0xC8, 0x0B, 0x28, 0x09, 0x3D, 0x81, 0x86, 0x93, 0xF5, 0xF6, 0xE4, 0x69, 0x3B, 0x60, 0x4C, 0x7F, 0x8D, 0x72, 0xA3, 0x22, 0x42, 0x86, 0x87, 0x06, 0xD8, 0x29, 0x89, 0x8A, 0x9F, 0x5F, 0x6C, 0x06, 0x0C, 0x96, 0x84, 0x00, 0x24, 0x5D, 0x0B, 0xEA, 0x15, 0xEC, 0xAD, 0x90, 0xA4, 0x0C, 0x7B, 0xAE, 0x0E, 0x85, 0x3E, 0xA2, 0x20, 0x04, 0xE8, 0xD9, 0x59, 0x0F, 0x31, 0x0E, 0xD4, 0x5D, 0xC1, 0x18, 0xED, 0x0E, 0xB4, 0xD2, 0x5E, 0x65, 0xA2, 0x78, 0x0C, 0x76, 0x03, 0x3A, 0x71, 0x18, 0xE4, 0x38, 0x44, 0x14, 0xE0, 0x93, 0x84, 0xFE, 0x34, 0x82, 0xCA, 0x0B, 0xB8, 0xF2, 0x41, 0xAB, 0x63, 0xF3, 0xDE, 0xAE, 0xF4, 0x36, 0x81, 0xA4, 0x78, 0x7B, 0xF9, 0xA8, 0xFB, 0xC9, 0xA7, 0x6E, 0xA4, 0xD5, 0xE2, 0xA9, 0xD8, 0xD9, 0xE8, 0x98, 0x1B, 0x25, 0x75, 0x00, 0x11, 0x51, 0x97, 0x62, 0x0D, 0xF0, 0x0C, 0xE9, 0x6B, 0x0C, 0xEE, 0xCE, 0x25, 0x2C, 0x3F, 0xDF, 0xBE, 0x54, 0xD5, 0xD6, 0x5E, 0xEE, 0x1F, 0x73, 0xFC, 0xE8, 0xEC, 0xB3, 0x8A, 0x48, 0x9F, 0x6A, 0xC1, 0x63, 0x85, 0xE4, 0x94, 0x85, 0x8F, 0x3D, 0x9D, 0x43, 0xB4, 0xA7, 0x4C, 0x82, 0xA3, 0x0B, 0x67, 0x43, 0x12, 0x31, 0x77, 0x89, 0xB0, 0xD5, 0x00, 0x1B, 0x52, 0x29, 0xCE, 0x54, 0xC7, 0xC4, 0x7D, 0xB6, 0x69, 0x7B, 0xFE, 0xDC, 0xDB, 0x4E, 0xD8, 0x58, 0x42, 0x14, 0x34, 0x72, 0x64, 0xBC, 0x09, 0x6D, 0xAC, 0xD3, 0xC4, 0x1B, 0x5C, 0x8E, 0xF9, 0xBE, 0x84, 0xCD, 0x9A, 0x86, 0x4B, 0x17 },
|
||||
.priv_exponent = { 0xAA, 0x51, 0x62, 0x58, 0x9A, 0xB5, 0x74, 0xDA, 0x1C, 0xC1, 0x4D, 0x7C, 0x81, 0xF6, 0x70, 0x99, 0x13, 0xCC, 0x90, 0x0D, 0xD9, 0xA0, 0x58, 0x01, 0x79, 0x1A, 0x53, 0xF9, 0x3C, 0xC0, 0x87, 0xF0, 0x35, 0x1A, 0x56, 0xA1, 0x2F, 0x6E, 0x93, 0x9A, 0xD5, 0x87, 0x12, 0x1B, 0x5C, 0xCC, 0xBC, 0xB9, 0x0E, 0xB8, 0xF7, 0x35, 0xD9, 0x23, 0x90, 0xE4, 0x19, 0x64, 0xCD, 0x7D, 0x24, 0xC2, 0x3A, 0xD6, 0x65, 0x38, 0xE7, 0xAD, 0xB2, 0xF9, 0x20, 0x13, 0xD4, 0xC5, 0xA4, 0x8C, 0xB6, 0xDC, 0x3C, 0x56, 0xF2, 0xFC, 0xF5, 0xB6, 0x92, 0xA6, 0xFE, 0x9B, 0x4E, 0xB7, 0x95, 0x8B, 0xAA, 0x2B, 0x70, 0x96, 0xA1, 0x27, 0xAB, 0xA6, 0x75, 0xC9, 0x77, 0x80, 0xE0, 0x65, 0x5D, 0x26, 0xD8, 0xE8, 0x14, 0xD3, 0x17, 0x46, 0x38, 0x58, 0xCC, 0xD8, 0x5A, 0x5A, 0x9F, 0x27, 0xCE, 0xD8, 0x7A, 0x19, 0xD7, 0x35, 0xB2, 0x32, 0xAF, 0x47, 0x2E, 0x9F, 0x4B, 0x64, 0xEC, 0x1F, 0xC6, 0x40, 0xD0, 0x2C, 0x47, 0xD1, 0xEA, 0x33, 0xE5, 0x0E, 0x80, 0xFC, 0x68, 0xEC, 0x8C, 0x12, 0x33, 0xCE, 0x34, 0x28, 0x79, 0xFA, 0x05, 0x5D, 0x70, 0x15, 0xDE, 0xB1, 0x22, 0x85, 0x18, 0x63, 0x15, 0x35, 0x57, 0x04, 0x17, 0x64, 0x20, 0xC8, 0x52, 0x44, 0x64, 0x5E, 0x47, 0x4E, 0x5F, 0x80, 0x21, 0x16, 0x94, 0x4B, 0x18, 0x11, 0x36, 0x67, 0x3B, 0x6C, 0x69, 0x19, 0xCF, 0xC9, 0x05, 0x85, 0x9B, 0x3A, 0xDE, 0x12, 0x1E, 0x0A, 0xC6, 0x22, 0xA8, 0xC7, 0x9A, 0x34, 0x14, 0x98, 0xFD, 0xD9, 0x0F, 0xE8, 0x64, 0xE6, 0x89, 0x63, 0x6E, 0x17, 0x76, 0xD7, 0x1B, 0x6F, 0x92, 0x00, 0xD8, 0xBB, 0xF6, 0xA0, 0x65, 0x9D, 0xAA, 0x7A, 0x0E, 0x4B, 0x56, 0xA5, 0x33, 0xDA, 0x3F, 0x5D, 0xFE, 0xD3, 0xAD, 0x6E, 0x0E, 0xB3, 0xD4, 0x41 },
|
||||
.access_desc_signature = { 0x97, 0x84, 0x97, 0xEE, 0x4F, 0x35, 0xCC, 0xBE, 0x08, 0xB4, 0x5D, 0x7E, 0x17, 0xC3, 0x94, 0x2B, 0x4D, 0x3A, 0xA5, 0xB5, 0x01, 0xD4, 0xAE, 0x2A, 0x90, 0x26, 0x21, 0x8F, 0x56, 0x05, 0xB9, 0xA2, 0x5E, 0xCE, 0x73, 0xC7, 0x42, 0xDC, 0x99, 0xD2, 0x7C, 0x08, 0x62, 0xBF, 0x10, 0x7A, 0xC1, 0x5D, 0x22, 0x53, 0x8F, 0x63, 0x2D, 0x73, 0xF3, 0x05, 0xDA, 0x9D, 0x6A, 0xF8, 0xB9, 0x5B, 0x80, 0xB4, 0x30, 0xB3, 0x11, 0xF7, 0x96, 0x8A, 0xCF, 0x70, 0xD7, 0x62, 0x6E, 0x99, 0x32, 0xFD, 0x74, 0x34, 0x16, 0xFD, 0x17, 0x1F, 0xB1, 0xEC, 0xA4, 0x0F, 0x52, 0x13, 0x9F, 0x62, 0x0D, 0xE0, 0x50, 0xA6, 0xA0, 0x7B, 0x69, 0x95, 0xE0, 0xE9, 0xBB, 0x38, 0x0C, 0x62, 0xE0, 0xE3, 0xCE, 0x82, 0xE0, 0xB9, 0xE0, 0xF6, 0x61, 0x50, 0xBF, 0xA8, 0x18, 0x15, 0x38, 0xFE, 0xFA, 0x8C, 0xBA, 0xA5, 0xB9, 0x9C, 0x05, 0xA6, 0x91, 0x5C, 0xA7, 0x13, 0x6F, 0x13, 0x3F, 0xF1, 0xF6, 0x68, 0xAF, 0x40, 0xEC, 0x27, 0xE0, 0x33, 0x6B, 0xCF, 0x26, 0x06, 0xF8, 0x6A, 0x13, 0x6C, 0xBC, 0xDB, 0xAF, 0x6F, 0x78, 0xA0, 0x80, 0x10, 0x8F, 0xB6, 0x91, 0x5A, 0x43, 0x2C, 0x5F, 0x1D, 0xBA, 0xB4, 0x5E, 0xBE, 0xAE, 0x53, 0x09, 0x17, 0x5B, 0x6C, 0xC1, 0x5E, 0x0F, 0x72, 0x6E, 0xD6, 0x10, 0x0B, 0xC3, 0x26, 0xDC, 0xAF, 0xCA, 0x28, 0xAB, 0x00, 0x67, 0x04, 0xE3, 0x54, 0xE8, 0x95, 0xC6, 0x23, 0xB6, 0x79, 0x70, 0xA4, 0x87, 0x6D, 0x12, 0x48, 0xCC, 0x11, 0x86, 0xEC, 0x82, 0xF4, 0x30, 0xC9, 0xB1, 0x6D, 0x08, 0xA7, 0xEA, 0x8C, 0x6A, 0x97, 0xAA, 0x89, 0xD5, 0xC5, 0x07, 0xA9, 0xD5, 0xCF, 0x09, 0x08, 0xBC, 0x56, 0x63, 0x8D, 0x70, 0x2F, 0x64, 0xAF, 0x51, 0x9E, 0x22, 0xA4, 0x88, 0xF0, 0xDC, 0x56, 0x72, 0x28 }
|
||||
},
|
||||
/* CTR_SDK 4 (4.2.8) */
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 33,
|
||||
.modulus = { 0xCF, 0xEC, 0xB2, 0x48, 0x03, 0x6D, 0xB8, 0x09, 0xE3, 0x5C, 0x6C, 0x62, 0x2C, 0xA9, 0x49, 0xE1, 0xF4, 0xF4, 0x0C, 0x6C, 0xC3, 0xE5, 0x2F, 0x9D, 0x50, 0xA0, 0x2B, 0x5A, 0x00, 0xC6, 0x72, 0x00, 0x0B, 0xA3, 0x04, 0x5D, 0x94, 0x46, 0xE7, 0x00, 0x1B, 0x48, 0x85, 0xB5, 0x61, 0x2C, 0xC9, 0x74, 0xCA, 0x2B, 0x43, 0x13, 0xC1, 0x78, 0x97, 0x5C, 0x33, 0x2F, 0x07, 0xC7, 0x85, 0xF0, 0xDA, 0xDB, 0x60, 0x96, 0x50, 0x0F, 0x7C, 0x4B, 0x7A, 0xD7, 0x17, 0x9D, 0xE4, 0xE5, 0xC3, 0xAB, 0x6F, 0x5D, 0xA5, 0x78, 0x32, 0xAD, 0x04, 0xDD, 0x96, 0x6E, 0xDC, 0x75, 0xFF, 0xC2, 0x2F, 0xFA, 0xA2, 0xEE, 0x46, 0x89, 0xCD, 0xAE, 0x69, 0x92, 0xA4, 0x48, 0xBC, 0x46, 0x47, 0xC4, 0x8C, 0x89, 0x63, 0xE1, 0x0A, 0x4D, 0x1C, 0xDC, 0x46, 0x2F, 0x5B, 0x70, 0x8A, 0x7C, 0xE9, 0x22, 0x9C, 0x09, 0x0B, 0xA8, 0x97, 0x40, 0xCA, 0x2A, 0x7D, 0x84, 0xA1, 0x04, 0x4A, 0x2E, 0xDB, 0xD7, 0xD0, 0x64, 0x43, 0x9C, 0xD0, 0x78, 0x11, 0x41, 0x88, 0x33, 0xDD, 0x31, 0x62, 0x90, 0x2D, 0x17, 0xF2, 0xC6, 0xA9, 0x2B, 0x9C, 0x70, 0xAB, 0xDC, 0xD3, 0xAB, 0x5D, 0xDA, 0xEE, 0x3D, 0x6C, 0x0E, 0x81, 0xFF, 0xF6, 0x67, 0x5A, 0x44, 0xF9, 0xAC, 0x07, 0x3D, 0x23, 0x94, 0x75, 0x65, 0x93, 0x20, 0x0C, 0xC5, 0x76, 0x1D, 0x0F, 0x65, 0x06, 0x3D, 0x21, 0xA2, 0xF0, 0x96, 0x80, 0xB7, 0x0A, 0x49, 0x53, 0x38, 0xA3, 0x5D, 0xC0, 0x74, 0x3C, 0xA4, 0xD9, 0x40, 0x36, 0x85, 0x1F, 0x8C, 0xD1, 0x2D, 0x15, 0xF9, 0xEF, 0x24, 0xA9, 0x7E, 0x9D, 0xB2, 0x1E, 0xF8, 0xA0, 0x72, 0x81, 0x17, 0x77, 0x73, 0xB1, 0x56, 0x7F, 0xAD, 0x05, 0xA2, 0xD2, 0x30, 0x5A, 0xF5, 0xD3, 0xAF, 0x0F, 0x10, 0x4A, 0x52, 0xD8, 0x09, 0x47, 0x97 },
|
||||
.priv_exponent = { 0x8C, 0xBD, 0xB2, 0x3B, 0xCE, 0x9E, 0x51, 0x09, 0xD8, 0x6D, 0x72, 0x2B, 0xCE, 0x01, 0x55, 0x32, 0x6E, 0xC5, 0x57, 0x37, 0xB4, 0x2E, 0x09, 0x59, 0xD9, 0xFE, 0x60, 0xF9, 0xCE, 0x36, 0x85, 0x6A, 0x04, 0x76, 0x76, 0xF9, 0x04, 0xEA, 0x2D, 0x68, 0xC4, 0x0F, 0x05, 0xFA, 0xAD, 0x69, 0x4C, 0x80, 0x12, 0x6C, 0xD0, 0x3D, 0xAA, 0x22, 0xFF, 0x89, 0x78, 0x57, 0xE8, 0x53, 0x25, 0x15, 0xD0, 0x7E, 0xD8, 0x55, 0x46, 0xA2, 0x04, 0xC7, 0x6E, 0xC1, 0xF3, 0x89, 0x7C, 0x2C, 0x0E, 0x93, 0x97, 0x91, 0x72, 0xF4, 0xF6, 0x90, 0x69, 0x0F, 0xB8, 0xC9, 0x17, 0xCF, 0x83, 0xAC, 0xA5, 0x1F, 0x69, 0x74, 0x12, 0x29, 0x2B, 0x21, 0x58, 0xF2, 0xDA, 0xE3, 0x25, 0x16, 0x09, 0x74, 0x40, 0x90, 0xAB, 0x1B, 0xE4, 0x06, 0x28, 0x77, 0xED, 0xC6, 0x16, 0x86, 0x0A, 0x27, 0xDD, 0x03, 0x01, 0x4D, 0x9A, 0x26, 0x6E, 0xC8, 0x9F, 0xD3, 0x9A, 0x4B, 0x59, 0xD1, 0x10, 0x9B, 0xEB, 0xA9, 0x58, 0x72, 0xBD, 0xA1, 0xFE, 0x9D, 0x86, 0xED, 0x29, 0xE9, 0x29, 0x49, 0x62, 0x4B, 0xD8, 0x7D, 0x2A, 0x7A, 0x66, 0x1B, 0xE5, 0x04, 0x81, 0x56, 0x10, 0x50, 0xAF, 0xB8, 0x48, 0x27, 0xC1, 0xC9, 0x46, 0xBD, 0x3F, 0x16, 0x06, 0xA5, 0x3D, 0x04, 0x9F, 0x0D, 0x54, 0x71, 0x1C, 0xF4, 0x82, 0xC0, 0x66, 0x74, 0xEA, 0x9C, 0x83, 0x3C, 0x27, 0x01, 0xDF, 0x6F, 0x56, 0xA8, 0x1B, 0xE3, 0x68, 0x55, 0x9F, 0xAB, 0x90, 0x67, 0x20, 0x25, 0xFA, 0x3D, 0x51, 0x2A, 0x23, 0x16, 0xCB, 0x06, 0x5A, 0xAD, 0xAC, 0xC8, 0x47, 0xF9, 0x39, 0x2E, 0x6A, 0xF8, 0xFA, 0x0A, 0xE8, 0x8A, 0x64, 0x84, 0x6B, 0xED, 0xDA, 0x8F, 0x2A, 0x08, 0x86, 0x8F, 0x56, 0x69, 0x64, 0xC3, 0x98, 0x55, 0x37, 0x9A, 0x48, 0x40, 0xDA, 0xD5, 0x03, 0x21 },
|
||||
.access_desc_signature = { 0xDF, 0x1C, 0x8B, 0x98, 0xE4, 0x6F, 0xA2, 0x35, 0x6C, 0xC3, 0x18, 0x17, 0x98, 0xF3, 0xCE, 0x54, 0x7E, 0x14, 0x2E, 0x7F, 0x1E, 0xD8, 0x6D, 0xCF, 0xBC, 0x29, 0x4E, 0xFE, 0x32, 0x2E, 0xC1, 0x11, 0xAD, 0x46, 0x9A, 0xC6, 0x70, 0xEA, 0xEE, 0x28, 0x55, 0x22, 0xE1, 0x36, 0x05, 0x1C, 0x04, 0x8A, 0xCE, 0x0F, 0x0C, 0x83, 0x8F, 0xC8, 0xD6, 0xDE, 0x11, 0x8E, 0xEA, 0xCF, 0xAD, 0x9B, 0xCF, 0x81, 0x0D, 0xEB, 0x71, 0x13, 0xB3, 0xD3, 0xAE, 0x83, 0x02, 0x4C, 0x0E, 0x10, 0x50, 0x59, 0x3C, 0xEE, 0x60, 0x06, 0xFB, 0x8C, 0x7F, 0xC2, 0x20, 0x24, 0x01, 0x62, 0x55, 0x87, 0x60, 0x0F, 0xAD, 0xFA, 0x73, 0x2E, 0xF6, 0x65, 0x62, 0xD2, 0xE5, 0x10, 0x45, 0x69, 0x70, 0x39, 0x03, 0xD1, 0x39, 0xEC, 0x50, 0xC1, 0xD4, 0x25, 0x39, 0xB2, 0x90, 0x11, 0x4E, 0x95, 0xCB, 0x19, 0xEB, 0xCA, 0x0F, 0xB5, 0xFA, 0xC7, 0xB0, 0xE2, 0xD7, 0xE0, 0x71, 0xC3, 0xE5, 0x55, 0x33, 0x9E, 0x5C, 0xDC, 0x4D, 0x3B, 0x51, 0x11, 0x0D, 0x31, 0x78, 0x96, 0xCA, 0xD7, 0x18, 0x58, 0xEE, 0x00, 0xE9, 0x28, 0xF2, 0x68, 0x76, 0xD4, 0x57, 0xFE, 0x65, 0xB1, 0x4B, 0x49, 0x3F, 0xF6, 0xA6, 0x58, 0x4A, 0xC7, 0xFC, 0xC4, 0xBB, 0x61, 0xBC, 0x58, 0x8D, 0x55, 0x65, 0xE6, 0x0A, 0x79, 0x39, 0x41, 0xB8, 0x80, 0x61, 0xF7, 0x05, 0xC3, 0xFE, 0xD6, 0x8B, 0x09, 0x82, 0xC2, 0x5F, 0xA6, 0x56, 0xF9, 0xEE, 0x1D, 0x0E, 0x06, 0x3E, 0x9F, 0x3F, 0xF1, 0x93, 0x9A, 0x4F, 0xA2, 0xD5, 0x91, 0x87, 0x8A, 0xFE, 0xCF, 0xC3, 0xFC, 0x8A, 0xB1, 0xC4, 0x78, 0xE9, 0xD1, 0x1A, 0xF7, 0xB1, 0xD3, 0x20, 0xCB, 0x83, 0xBE, 0x03, 0xD5, 0xCA, 0xA5, 0x5E, 0x17, 0xA6, 0x91, 0x10, 0xD4, 0xBE, 0x23, 0xD6, 0x4B, 0x4F, 0x03, 0xA9, 0xAE }
|
||||
},
|
||||
{
|
||||
.type = desc_DlpChild,
|
||||
.fw_minor = 33,
|
||||
.modulus = { 0xB3, 0x16, 0x68, 0xF1, 0xED, 0x59, 0xC8, 0x7F, 0xC6, 0x50, 0x21, 0xFE, 0x36, 0x7C, 0x55, 0xE7, 0x07, 0xF9, 0x1D, 0x1B, 0xF5, 0xB1, 0x2A, 0x6B, 0x3A, 0xDE, 0x2D, 0x4C, 0x51, 0xCD, 0x4C, 0x9F, 0xEE, 0x1D, 0xE4, 0xE8, 0xF0, 0xFD, 0x09, 0x8E, 0x0F, 0x92, 0x5F, 0xDB, 0x9C, 0x5C, 0x15, 0x55, 0x1A, 0x4D, 0x04, 0x8C, 0xB0, 0xA4, 0x88, 0x97, 0xC4, 0xD5, 0x92, 0x04, 0x42, 0x33, 0x84, 0x81, 0x06, 0xD6, 0xF2, 0x17, 0xDE, 0x83, 0x17, 0x50, 0xD0, 0x47, 0x61, 0x14, 0x0D, 0xB7, 0xC7, 0xA0, 0xC1, 0x8B, 0x82, 0x47, 0x13, 0xEE, 0x76, 0xA2, 0xA3, 0x8D, 0xCE, 0x55, 0xC1, 0xF3, 0x7A, 0xEA, 0x91, 0xE1, 0xB9, 0x2F, 0x8F, 0x9B, 0xC3, 0x7B, 0x51, 0x2F, 0xE7, 0xAD, 0x93, 0x9C, 0xFD, 0xDF, 0x19, 0xC8, 0x6C, 0x24, 0xC2, 0xE2, 0x91, 0x97, 0x1F, 0xEB, 0x4B, 0xD4, 0x46, 0x6C, 0x06, 0x93, 0xAF, 0xF5, 0x5E, 0x8F, 0x77, 0x25, 0xC4, 0x28, 0xC0, 0x82, 0x4A, 0x78, 0xE9, 0x14, 0x08, 0xC3, 0xC3, 0x58, 0x24, 0x44, 0x2D, 0x2B, 0xA7, 0xEE, 0x28, 0xEF, 0x1B, 0x6D, 0xAA, 0x9C, 0xED, 0x7F, 0x35, 0xCE, 0x86, 0x5C, 0x6B, 0x8A, 0x23, 0xD3, 0x9D, 0x05, 0x8F, 0xD2, 0x41, 0x93, 0x1D, 0x1D, 0x7E, 0xB0, 0x46, 0x23, 0x63, 0x07, 0xEA, 0x5F, 0x26, 0xE3, 0x81, 0x27, 0xB3, 0x95, 0xB1, 0x93, 0x59, 0xD4, 0x1A, 0xB8, 0x73, 0xD0, 0x09, 0x95, 0x2B, 0xE8, 0x8B, 0xE2, 0x73, 0x5F, 0x34, 0xB9, 0x98, 0x82, 0xF0, 0x11, 0xC6, 0x8F, 0x12, 0x4D, 0x09, 0x57, 0x10, 0x97, 0x22, 0x0E, 0xC8, 0x7D, 0x40, 0xC1, 0x9D, 0x12, 0x1F, 0x71, 0xFE, 0x1E, 0x1A, 0x8C, 0x3F, 0x56, 0xAC, 0x43, 0xC3, 0x66, 0x0C, 0x81, 0xAE, 0xC1, 0x8F, 0x68, 0xFF, 0x87, 0x07, 0x3C, 0xCD, 0x0A, 0x23, 0xDE, 0xBA, 0x9B },
|
||||
.priv_exponent = { 0x77, 0xC2, 0x7A, 0xB7, 0x9E, 0x13, 0xB6, 0x62, 0xCC, 0x09, 0x76, 0x51, 0xFB, 0xB9, 0xB5, 0xF0, 0x63, 0x82, 0x91, 0x96, 0xCA, 0xFC, 0x88, 0xF3, 0x60, 0x50, 0x87, 0x56, 0x4C, 0x35, 0xD0, 0x11, 0xFB, 0x38, 0x7E, 0x85, 0xCF, 0xF2, 0x46, 0xDB, 0x7B, 0x4A, 0x55, 0x54, 0x15, 0x01, 0xF7, 0x3A, 0x0B, 0xF6, 0x89, 0x1E, 0x54, 0x5A, 0x13, 0x05, 0xFB, 0x19, 0x1F, 0x26, 0x3D, 0xE7, 0x19, 0xAA, 0xF7, 0x19, 0xF2, 0x97, 0x47, 0xB3, 0xBE, 0x79, 0xCA, 0x6E, 0x91, 0x5A, 0xC9, 0xB9, 0xA6, 0x83, 0xB8, 0x2A, 0x45, 0x1A, 0xA7, 0x17, 0x86, 0xBA, 0x48, 0x49, 0x62, 0x3C, 0x33, 0x11, 0x51, 0x97, 0x5F, 0xAA, 0xE5, 0x1E, 0x0B, 0x19, 0x0C, 0xE6, 0x80, 0x6A, 0x5A, 0xB1, 0xD6, 0xCE, 0xDB, 0x6E, 0xC0, 0x5D, 0x29, 0x04, 0x84, 0x56, 0xE3, 0x29, 0x7E, 0xAC, 0xE8, 0xEE, 0xB1, 0x91, 0x37, 0xEB, 0x98, 0x9C, 0xBD, 0x02, 0x6A, 0x78, 0x61, 0xB0, 0x79, 0x1A, 0x9F, 0x30, 0x86, 0xF6, 0x71, 0x5A, 0x5A, 0x12, 0xA1, 0x9E, 0xA1, 0x68, 0x03, 0xE5, 0x95, 0xA8, 0x38, 0x58, 0x87, 0x08, 0x57, 0x35, 0x32, 0x47, 0x3B, 0xFC, 0x02, 0x6F, 0xCE, 0x55, 0x61, 0xA3, 0x2A, 0x6B, 0x2F, 0xF8, 0xEE, 0x8D, 0xFA, 0x43, 0x33, 0x02, 0x63, 0x47, 0x02, 0x78, 0x5A, 0x7F, 0x64, 0x07, 0x92, 0xB7, 0x7C, 0x09, 0x7C, 0xFE, 0x2D, 0x1C, 0xFC, 0x77, 0x9F, 0x19, 0x20, 0xDD, 0x6D, 0x4C, 0xFE, 0x49, 0x09, 0x47, 0xCA, 0x9B, 0x1C, 0x8C, 0x1F, 0x37, 0xAC, 0x14, 0x85, 0x56, 0xC0, 0xFD, 0xD6, 0x01, 0xB3, 0x40, 0xA3, 0x1A, 0x32, 0x78, 0xA0, 0xDD, 0x21, 0x75, 0xBF, 0x24, 0xD2, 0x93, 0x85, 0xED, 0x22, 0xAD, 0x99, 0x91, 0x87, 0x4A, 0xEC, 0xC0, 0x6C, 0x71, 0x00, 0x76, 0x08, 0x23, 0xA2, 0xF3, 0xCF, 0x61 },
|
||||
.access_desc_signature = { 0xAC, 0xE2, 0xA7, 0xC3, 0x00, 0xDE, 0xE8, 0xE9, 0xE0, 0x03, 0xB3, 0x54, 0x08, 0xA8, 0xF8, 0x3A, 0x2E, 0xD8, 0x10, 0x6B, 0xEC, 0xDC, 0x4E, 0xEE, 0x62, 0x10, 0x71, 0x49, 0xD4, 0x43, 0xB1, 0x0E, 0x6B, 0x8C, 0xD7, 0x54, 0xD5, 0x62, 0x28, 0x3F, 0xAA, 0xDE, 0xA9, 0x7D, 0xED, 0x37, 0x7C, 0xE7, 0x89, 0x0B, 0x02, 0xB2, 0x72, 0x4B, 0x17, 0xDB, 0xE2, 0xD3, 0x7C, 0x94, 0x12, 0x3F, 0x2E, 0xA1, 0x08, 0x99, 0xCC, 0x7F, 0x93, 0xE6, 0x38, 0xC9, 0x37, 0x84, 0xD7, 0x11, 0x9D, 0x02, 0x4D, 0x66, 0xB4, 0x70, 0x9F, 0xD8, 0xC6, 0xDD, 0xD5, 0x13, 0x52, 0xF0, 0xA6, 0x78, 0x8C, 0x8E, 0x15, 0xA0, 0xA1, 0xF3, 0xC4, 0xC3, 0x48, 0x45, 0xA5, 0xBE, 0xC9, 0x7A, 0x8B, 0xD3, 0x95, 0xA5, 0x4C, 0xF1, 0xB3, 0x0C, 0x6C, 0x76, 0xA7, 0x57, 0xA1, 0x77, 0xDF, 0x2F, 0xC8, 0x06, 0xA6, 0x0D, 0x1A, 0x09, 0xE4, 0x38, 0x64, 0x07, 0xBE, 0x6A, 0xD2, 0xA0, 0xC0, 0xEC, 0x09, 0x64, 0x9F, 0x0D, 0x93, 0x0C, 0x89, 0xA2, 0x71, 0xD6, 0xC6, 0xC2, 0x54, 0x79, 0x2A, 0xA4, 0x31, 0x28, 0x24, 0x1A, 0xF3, 0x56, 0x78, 0x63, 0x99, 0x97, 0xA5, 0xCE, 0x8F, 0x52, 0x7A, 0x79, 0x51, 0xEE, 0x4C, 0x8B, 0x00, 0x9D, 0x5C, 0x3E, 0xD5, 0xAA, 0x24, 0x9C, 0x94, 0xC6, 0xA3, 0x99, 0x1B, 0x2D, 0xD4, 0xFF, 0xB4, 0x25, 0x73, 0x13, 0x33, 0x9F, 0x03, 0x6F, 0x1E, 0x75, 0xC4, 0x70, 0xF4, 0x07, 0x4F, 0x18, 0xFE, 0xBD, 0x8F, 0x2C, 0x9B, 0x33, 0xD4, 0x30, 0xA7, 0x18, 0x4A, 0xF1, 0xA4, 0xDD, 0x78, 0x41, 0xA0, 0xB8, 0x02, 0x8D, 0x51, 0x96, 0xBE, 0xE7, 0x17, 0x94, 0x66, 0x65, 0x27, 0xF7, 0x69, 0x48, 0x7E, 0xA9, 0x08, 0x71, 0x20, 0x76, 0xB7, 0x8E, 0xD2, 0xBF, 0x5C, 0x7E, 0x5E, 0x06, 0x45, 0xAB, 0x7E, 0x2E }
|
||||
},
|
||||
{
|
||||
.type = desc_Demo,
|
||||
.fw_minor = 33,
|
||||
.modulus = { 0xB5, 0x11, 0x8D, 0x9E, 0x2D, 0xDB, 0x70, 0x6D, 0x6E, 0xEE, 0xAA, 0x21, 0xE0, 0x4E, 0x80, 0x0A, 0x96, 0x4A, 0x10, 0xD0, 0x9C, 0xD7, 0xD9, 0xD4, 0x94, 0x87, 0x72, 0xA2, 0xAF, 0x02, 0xA0, 0x05, 0x2E, 0xBF, 0x17, 0xEB, 0xFE, 0x5B, 0x9F, 0xB7, 0x0B, 0x1E, 0x3E, 0xF9, 0xAC, 0xBC, 0x7B, 0xB1, 0x56, 0x10, 0x24, 0x5F, 0x57, 0x2C, 0x08, 0xD0, 0x14, 0x79, 0x83, 0x84, 0x6A, 0x45, 0x25, 0xEB, 0xD9, 0xBE, 0x02, 0x21, 0xF7, 0x35, 0xC2, 0x74, 0x57, 0xC5, 0xAC, 0x34, 0x05, 0xC6, 0x9E, 0x82, 0xB8, 0xED, 0x78, 0xC4, 0x3B, 0xFD, 0x23, 0x59, 0x54, 0xD2, 0x0A, 0x0B, 0x5B, 0x25, 0xC0, 0x71, 0xC3, 0x84, 0x3A, 0xA7, 0xF9, 0x99, 0x86, 0xD8, 0xFE, 0x60, 0x10, 0x85, 0x77, 0x57, 0x76, 0x0C, 0x25, 0xE1, 0x18, 0x18, 0x3B, 0x83, 0xFD, 0x36, 0x7C, 0x84, 0x58, 0xC2, 0xC4, 0x68, 0x4F, 0xD1, 0xD7, 0x0A, 0x88, 0xFD, 0xCA, 0x97, 0xA1, 0xE5, 0xCE, 0x72, 0x63, 0xCF, 0x74, 0xD0, 0x20, 0xD9, 0xDE, 0x3F, 0xBB, 0x11, 0xF9, 0x21, 0xAB, 0x3F, 0x54, 0x41, 0xA7, 0xAA, 0xCA, 0xFC, 0xE1, 0x1A, 0x8C, 0x12, 0xC9, 0x39, 0x13, 0x5A, 0x81, 0x29, 0x49, 0xE8, 0xFB, 0x48, 0xC9, 0x4D, 0x50, 0x87, 0xAE, 0x51, 0xFB, 0x94, 0xFC, 0xF0, 0x9C, 0x70, 0x1C, 0xE8, 0x6E, 0x44, 0x53, 0x1E, 0x2F, 0x27, 0x5C, 0xB8, 0xEC, 0xBE, 0xFC, 0xD9, 0x98, 0x6A, 0x08, 0xD0, 0x5C, 0x4D, 0x78, 0x2D, 0x4D, 0x07, 0xAD, 0x5E, 0xB8, 0x51, 0x40, 0xE2, 0x2A, 0x7F, 0xB1, 0x54, 0x47, 0x5C, 0x99, 0x12, 0xC2, 0x6D, 0x5E, 0xED, 0x25, 0x30, 0x6A, 0x99, 0xC5, 0x0D, 0x65, 0x83, 0x68, 0x3A, 0xFD, 0x82, 0x59, 0x0D, 0xCE, 0x0B, 0x49, 0xBE, 0x17, 0x46, 0x51, 0xA9, 0xB6, 0x54, 0xE1, 0x18, 0xBD, 0x49, 0xE6, 0x7F },
|
||||
.priv_exponent = { 0x1D, 0x7B, 0x79, 0x32, 0xAB, 0x46, 0xD2, 0xBC, 0x8E, 0xD6, 0x7F, 0x8F, 0x3A, 0x85, 0xAD, 0xA5, 0x8B, 0xA9, 0x0D, 0xA9, 0xDA, 0x0F, 0xEF, 0x61, 0x04, 0xBA, 0x35, 0x39, 0x36, 0x03, 0xD8, 0x68, 0x5F, 0x9F, 0x2F, 0xD6, 0xF6, 0x38, 0x96, 0xFD, 0xE7, 0xEA, 0x89, 0xD8, 0x7F, 0x7E, 0xC5, 0x29, 0x2F, 0xD9, 0x3B, 0x02, 0xE7, 0x1F, 0xBD, 0x63, 0x9C, 0x21, 0xD8, 0xFF, 0x43, 0x8A, 0x74, 0xCD, 0x3D, 0x4C, 0x09, 0xEE, 0xDB, 0xE0, 0xBE, 0x03, 0xD1, 0x92, 0xD7, 0x22, 0x35, 0x5A, 0x8C, 0xCE, 0xBE, 0x2B, 0xB4, 0x81, 0x47, 0x3F, 0x45, 0x75, 0x33, 0x31, 0x6B, 0xFF, 0x43, 0x5D, 0x17, 0x43, 0xAE, 0xD1, 0x25, 0xF7, 0xD9, 0xD5, 0x5C, 0xB6, 0x92, 0x5C, 0xB3, 0xF3, 0xF7, 0x65, 0x9F, 0x4C, 0x05, 0x12, 0xEC, 0xA8, 0x6D, 0x70, 0x65, 0x57, 0x6C, 0xD8, 0xE3, 0xD6, 0xFA, 0xC1, 0xFD, 0x54, 0xE8, 0x34, 0x67, 0x4D, 0x0A, 0x14, 0x2F, 0xA3, 0xD4, 0x81, 0x8C, 0xC3, 0xD0, 0x8B, 0x09, 0x08, 0x90, 0x70, 0x68, 0xA0, 0x0E, 0xD1, 0x0B, 0xAA, 0x71, 0xEC, 0x9A, 0x1A, 0x83, 0xFF, 0xA1, 0x70, 0xEB, 0xAC, 0xF2, 0xE9, 0x80, 0xA1, 0xB8, 0x20, 0x31, 0x83, 0xF5, 0x37, 0x01, 0x72, 0x06, 0x50, 0x05, 0x3F, 0x14, 0xF9, 0x29, 0x48, 0x84, 0xA0, 0x0E, 0xF7, 0xB8, 0x1D, 0xA3, 0x36, 0x5A, 0x78, 0x6D, 0x83, 0x90, 0x27, 0xE3, 0x50, 0x49, 0x2F, 0x65, 0xE5, 0x61, 0xED, 0x65, 0xBE, 0xEA, 0x34, 0xA6, 0x6A, 0xEF, 0x49, 0xB4, 0xE0, 0xBC, 0xC2, 0xA5, 0xB8, 0xEB, 0xA9, 0x2F, 0xBA, 0x26, 0x76, 0xB2, 0x5A, 0x3A, 0x3B, 0xFD, 0xAD, 0xFB, 0xE4, 0x79, 0xE2, 0x85, 0x54, 0x5B, 0xAB, 0x1F, 0x0A, 0xE5, 0x8B, 0x77, 0x3A, 0x10, 0x98, 0x26, 0x74, 0xC8, 0xB0, 0x82, 0xB1, 0xF9, 0x8F, 0x68, 0x59 },
|
||||
.access_desc_signature = { 0xD3, 0x7D, 0x42, 0xBA, 0x6A, 0x1E, 0xD8, 0x07, 0x3C, 0x4A, 0xC4, 0xCD, 0x8C, 0x68, 0x3D, 0xCD, 0xCD, 0xBD, 0x9D, 0xCE, 0xB5, 0x2A, 0xF9, 0x63, 0x3D, 0xA9, 0x54, 0x0A, 0x2E, 0x4C, 0xE1, 0x60, 0x4B, 0xD0, 0xC9, 0xEB, 0xEF, 0x31, 0x65, 0x70, 0xB9, 0x0E, 0x06, 0x3B, 0x3D, 0x42, 0x4C, 0x6E, 0x8D, 0x2C, 0xD4, 0x71, 0x29, 0x76, 0xB7, 0xDD, 0x8C, 0xDA, 0xE7, 0xE3, 0x96, 0xA7, 0xAA, 0xF8, 0xCA, 0x05, 0xE8, 0xA7, 0x0A, 0xDD, 0x01, 0x49, 0xBD, 0xF1, 0xA5, 0xE8, 0x16, 0x22, 0xEE, 0x47, 0x1F, 0xEF, 0x28, 0x48, 0x87, 0xA9, 0x2D, 0xFC, 0x4E, 0xD5, 0xA5, 0x98, 0xB1, 0xFE, 0x1B, 0xEB, 0xA9, 0x06, 0x3C, 0x76, 0xD9, 0xAA, 0x0E, 0x9C, 0x60, 0xFC, 0xE9, 0x77, 0x9D, 0x7F, 0x67, 0xAC, 0xF5, 0xC7, 0x49, 0x12, 0xFD, 0x76, 0xAC, 0xD2, 0x54, 0xDB, 0x73, 0x41, 0x10, 0x1F, 0x04, 0x3F, 0xD0, 0x6F, 0xE0, 0x80, 0x24, 0xCC, 0xEE, 0xBF, 0x25, 0x9D, 0x0D, 0x5A, 0x2A, 0x1C, 0xC5, 0xD4, 0xE3, 0x5D, 0x3A, 0xC1, 0x86, 0xD3, 0xD4, 0x52, 0x1C, 0x4C, 0xBF, 0x31, 0xEB, 0x54, 0xCA, 0x4C, 0x06, 0x50, 0x52, 0x87, 0xD4, 0x9D, 0x4A, 0x4B, 0x22, 0xE1, 0x4A, 0xE9, 0x4D, 0x05, 0xA8, 0x57, 0xEC, 0xF8, 0x90, 0xF8, 0x58, 0xC3, 0x8B, 0x3A, 0x0F, 0x88, 0x36, 0xF4, 0xE5, 0x44, 0x10, 0x80, 0x68, 0x86, 0x1D, 0xAE, 0x90, 0x20, 0x03, 0x22, 0x2D, 0x44, 0xBF, 0xAB, 0x2B, 0xA1, 0x14, 0xAD, 0x6B, 0x40, 0x57, 0xDB, 0xBB, 0xDA, 0x09, 0x4C, 0x51, 0x26, 0x9B, 0xE3, 0xD9, 0xF9, 0xE1, 0xBC, 0xF1, 0xF1, 0xCD, 0x30, 0xB4, 0xF5, 0x39, 0xD0, 0xBC, 0xF7, 0x98, 0x05, 0xAF, 0xA8, 0x33, 0x4B, 0xC1, 0x16, 0x0F, 0xF2, 0xC2, 0x79, 0x96, 0xEC, 0xBE, 0xA9, 0xF5, 0x55, 0x7C, 0x82, 0x95, 0x73 }
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,132 @@
|
||||
#pragma once
|
||||
#include "desc.h"
|
||||
|
||||
static const CtrSdkDesc kDescPresets[] =
|
||||
{
|
||||
/* CTR_SDK 1 (1.2.0) (2.27 - 2.28) */
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 27,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
{
|
||||
.type = desc_DlpChild,
|
||||
.fw_minor = 27,
|
||||
.exheader_desc = { 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
/* CTR_SDK 2 (2.3.4) */
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 29,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x1D, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x1D, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
{
|
||||
.type = desc_DlpChild,
|
||||
.fw_minor = 29,
|
||||
.exheader_desc = { 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x1D, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x1D, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 30,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x1E, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x1E, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
{
|
||||
.type = desc_Demo,
|
||||
.fw_minor = 30,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x1E, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFB, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x1E, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
/* CTR_SDK 3 (3.2.5) (2.32) */
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 32,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x20, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x20, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
{
|
||||
.type = desc_EcApplication,
|
||||
.fw_minor = 32,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6E, 0x69, 0x6D, 0x3A, 0x61, 0x6F, 0x63, 0x00, 0x61, 0x6D, 0x3A, 0x61, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x20, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6E, 0x69, 0x6D, 0x3A, 0x61, 0x6F, 0x63, 0x00, 0x61, 0x6D, 0x3A, 0x61, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x20, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
/* CTR_SDK 4 (4.2.8) (2.33) */
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 33,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x21, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x21, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
{
|
||||
.type = desc_DlpChild,
|
||||
.fw_minor = 33,
|
||||
.exheader_desc = { 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x21, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x21, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
{
|
||||
.type = desc_Demo,
|
||||
.fw_minor = 33,
|
||||
.exheader_desc = { 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x21, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x21, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
/* CTR_SDK 5 (5.2.3) (2.35) */
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 35,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x23, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x23, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
{
|
||||
.type = desc_EcApplication,
|
||||
.fw_minor = 35,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6E, 0x69, 0x6D, 0x3A, 0x61, 0x6F, 0x63, 0x00, 0x61, 0x6D, 0x3A, 0x61, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x23, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6E, 0x69, 0x6D, 0x3A, 0x61, 0x6F, 0x63, 0x00, 0x61, 0x6D, 0x3A, 0x61, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x23, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
/* SDK 7 (7.1.0) (2.39) */
|
||||
{
|
||||
.type = desc_Application,
|
||||
.fw_minor = 39,
|
||||
.exheader_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x41, 0x00, 0x00, 0x00, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x74, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x61, 0x6D, 0x3A, 0x61, 0x70, 0x70, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x69, 0x6D, 0x3A, 0x61, 0x6F, 0x63, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x27, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.signed_desc = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x18, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x68, 0x69, 0x6F, 0x46, 0x49, 0x4F, 0x00, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x30, 0x24, 0x68, 0x6F, 0x73, 0x74, 0x69, 0x6F, 0x31, 0x63, 0x66, 0x67, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x66, 0x73, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x67, 0x73, 0x70, 0x3A, 0x3A, 0x47, 0x70, 0x75, 0x68, 0x69, 0x64, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x6E, 0x64, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x70, 0x78, 0x69, 0x3A, 0x64, 0x65, 0x76, 0x00, 0x41, 0x50, 0x54, 0x3A, 0x41, 0x00, 0x00, 0x00, 0x61, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x61, 0x63, 0x74, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x61, 0x6D, 0x3A, 0x61, 0x70, 0x70, 0x00, 0x00, 0x62, 0x6F, 0x73, 0x73, 0x3A, 0x55, 0x00, 0x00, 0x63, 0x61, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x63, 0x65, 0x63, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x64, 0x6C, 0x70, 0x3A, 0x46, 0x4B, 0x43, 0x4C, 0x64, 0x6C, 0x70, 0x3A, 0x53, 0x52, 0x56, 0x52, 0x64, 0x73, 0x70, 0x3A, 0x3A, 0x44, 0x53, 0x50, 0x66, 0x72, 0x64, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x43, 0x00, 0x00, 0x69, 0x72, 0x3A, 0x55, 0x53, 0x45, 0x52, 0x00, 0x6C, 0x64, 0x72, 0x3A, 0x72, 0x6F, 0x00, 0x00, 0x6D, 0x69, 0x63, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x6E, 0x65, 0x77, 0x73, 0x3A, 0x75, 0x00, 0x00, 0x6E, 0x69, 0x6D, 0x3A, 0x61, 0x6F, 0x63, 0x00, 0x6E, 0x77, 0x6D, 0x3A, 0x3A, 0x55, 0x44, 0x53, 0x70, 0x74, 0x6D, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x73, 0x6F, 0x63, 0x3A, 0x55, 0x00, 0x00, 0x00, 0x73, 0x73, 0x6C, 0x3A, 0x43, 0x00, 0x00, 0x00, 0x79, 0x32, 0x72, 0x3A, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9F, 0xFA, 0xF0, 0xFF, 0xBF, 0xFF, 0xF1, 0xE7, 0x3F, 0x00, 0xF2, 0x00, 0xF0, 0x91, 0xFF, 0x00, 0xF6, 0x91, 0xFF, 0x50, 0xFF, 0x81, 0xFF, 0x58, 0xFF, 0x81, 0xFF, 0x70, 0xFF, 0x81, 0xFF, 0x78, 0xFF, 0x81, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0x00, 0x02, 0x00, 0xFE, 0x27, 0x02, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }
|
||||
},
|
||||
};
|
||||
|
||||
static const CtrSdkDepList kExheaderDependencyLists[] =
|
||||
{
|
||||
{
|
||||
.fw_minor = 27,
|
||||
.dependency = { 0x02, 0x24, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x15, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x34, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x16, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x26, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x17, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x27, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x28, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1A, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x32, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x29, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x20, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x35, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x21, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x31, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x22, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x23, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
},
|
||||
{
|
||||
.fw_minor = 28,
|
||||
.dependency = { 0x02, 0x24, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x15, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x34, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x16, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x26, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x17, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x27, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x28, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1A, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x32, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x29, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x20, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x35, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x21, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x31, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x22, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x23, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
},
|
||||
{
|
||||
.fw_minor = 29,
|
||||
.dependency = { 0x02, 0x24, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x15, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x34, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x16, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x26, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x17, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x27, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x28, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1A, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x32, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x29, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x20, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x35, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x21, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x31, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x22, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x23, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
},
|
||||
{
|
||||
.fw_minor = 30,
|
||||
.dependency = { 0x02, 0x24, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x15, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x34, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x16, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x26, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x17, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x27, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x28, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1A, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x32, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x29, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x20, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x35, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x21, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x31, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x22, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x23, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
},
|
||||
{
|
||||
.fw_minor = 32,
|
||||
.dependency = { 0x02, 0x24, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x15, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x34, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x16, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x26, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x17, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x27, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x28, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1A, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x32, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x29, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x33, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x20, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x35, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x21, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x31, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x22, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x37, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x23, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
},
|
||||
{
|
||||
.fw_minor = 33,
|
||||
.dependency = { 0x02, 0x24, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x15, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x34, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x16, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x26, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x17, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x27, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x28, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1A, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x32, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x29, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x33, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x20, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x35, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x21, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x31, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x22, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x37, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x23, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
},
|
||||
{
|
||||
.fw_minor = 35,
|
||||
.dependency = { 0x02, 0x24, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x15, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x34, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x16, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x26, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x17, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x27, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x28, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1A, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x32, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x29, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x33, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x20, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x35, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x21, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x31, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x22, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x37, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x23, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
},
|
||||
{
|
||||
.fw_minor = 39,
|
||||
.dependency = { 0x02, 0x24, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x38, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x15, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x34, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x16, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x26, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x17, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x27, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x28, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1A, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x32, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x29, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x33, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x20, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2B, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x35, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2D, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x21, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x31, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x22, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x37, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2E, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x23, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x02, 0x2F, 0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,194 @@
|
||||
#include "lib.h"
|
||||
#include "elf.h"
|
||||
|
||||
static const u32 ELF_MAGIC = 0x7f454c46;
|
||||
|
||||
typedef enum elf_bit_format_types
|
||||
{
|
||||
elf_32_bit = 1,
|
||||
elf_64_bit = 2,
|
||||
} elf_bit_format_types;
|
||||
|
||||
typedef enum elf_endianness
|
||||
{
|
||||
elf_little_endian = 1,
|
||||
elf_big_endian = 2,
|
||||
} elf_endianness;
|
||||
|
||||
typedef enum elf_type
|
||||
{
|
||||
elf_relocatable = 1,
|
||||
elf_executeable = 2,
|
||||
elf_shared = 3,
|
||||
elf_core = 4,
|
||||
} elf_type;
|
||||
|
||||
typedef enum elf_target_architecture
|
||||
{
|
||||
elf_arm = 0x28,
|
||||
} elf_target_architecture;
|
||||
|
||||
typedef struct elf_hdr
|
||||
{
|
||||
u8 magic[4];
|
||||
u8 bitFormat;
|
||||
u8 endianness;
|
||||
u8 elfVersion;
|
||||
u8 os;
|
||||
u8 padding0[8];
|
||||
u8 type[2];
|
||||
u8 targetArchitecture[2];
|
||||
u8 version[4];
|
||||
u8 entryPoint[4];
|
||||
u8 programHeaderTableOffset[4];
|
||||
u8 sectionHeaderTableOffset[4];
|
||||
u8 flags[4];
|
||||
u8 headerSize[2];
|
||||
u8 programHeaderEntrySize[2];
|
||||
u8 programHeaderEntryCount[2];
|
||||
u8 sectionTableEntrySize[2];
|
||||
u8 sectionHeaderEntryCount[2];
|
||||
u8 sectionHeaderNameEntryIndex[2];
|
||||
} elf_hdr;
|
||||
|
||||
/* taken from elf specs, will not follow global style */
|
||||
|
||||
/* Section header. */
|
||||
typedef struct elf_shdr
|
||||
{
|
||||
u8 name[4]; /* Section name (string tbl index) */
|
||||
u8 type[4]; /* Section type */
|
||||
u8 flags[4]; /* Section flags */
|
||||
u8 addr[4]; /* Section virtual addr at execution */
|
||||
u8 offset[4]; /* Section file offset */
|
||||
u8 size[4]; /* Section size in bytes */
|
||||
u8 link[4]; /* Link to another section */
|
||||
u8 info[4]; /* Additional section information */
|
||||
u8 addralign[4]; /* Section alignment */
|
||||
u8 entsize[4]; /* Entry size if section holds table */
|
||||
} elf_shdr;
|
||||
|
||||
/* Program segment header. */
|
||||
typedef struct elf_phdr
|
||||
{
|
||||
u8 type[4]; /* Segment type */
|
||||
u8 offset[4]; /* Segment file offset */
|
||||
u8 vaddr[4]; /* Segment virtual address */
|
||||
u8 paddr[4]; /* Segment physical address */
|
||||
u8 filesz[4]; /* Segment size in file */
|
||||
u8 memsz[4]; /* Segment size in memory */
|
||||
u8 flags[4]; /* Segment flags */
|
||||
u8 align[4]; /* Segment alignment */
|
||||
} elf_phdr;
|
||||
|
||||
// ELF Functions
|
||||
|
||||
int elf_ProcessHeader(elf_context *elf)
|
||||
{
|
||||
const elf_hdr *hdr = (const elf_hdr*)elf->file;
|
||||
|
||||
/* Check conditions for valid CTR ELF */
|
||||
if (u8_to_u32(hdr->magic, BE) != ELF_MAGIC)
|
||||
return NOT_ELF_FILE;
|
||||
if (hdr->bitFormat != elf_32_bit)
|
||||
return NOT_CTR_ARM_ELF;
|
||||
if (hdr->endianness != elf_little_endian)
|
||||
return NOT_CTR_ARM_ELF;
|
||||
if (u8_to_u16(hdr->targetArchitecture, LE) != elf_arm)
|
||||
return NOT_CTR_ARM_ELF;
|
||||
if (u8_to_u16(hdr->type, LE) != elf_executeable)
|
||||
return NON_EXECUTABLE_ELF;
|
||||
|
||||
elf->phdrOffset = u8_to_u32(hdr->programHeaderTableOffset, LE);
|
||||
elf->segmentNum = u8_to_u16(hdr->programHeaderEntryCount, LE);
|
||||
elf->segments = calloc(elf->segmentNum, sizeof(elf_segment));
|
||||
if (!elf->segments) {
|
||||
fprintf(stderr, "[ELF ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
|
||||
elf->shdrOffset = u8_to_u32(hdr->sectionHeaderTableOffset, LE);
|
||||
elf->shdrNameIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex, LE);
|
||||
elf->sectionNum = u8_to_u16(hdr->sectionHeaderEntryCount, LE);
|
||||
elf->sections = calloc(elf->sectionNum, sizeof(elf_section));
|
||||
if (!elf->sections) {
|
||||
fprintf(stderr, "[ELF ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void elf_PopulateSections(elf_context *elf)
|
||||
{
|
||||
const elf_shdr *shdr = (const elf_shdr *)(elf->file + elf->shdrOffset);
|
||||
const char *nameTable = (const char*)(elf->file + u8_to_u32(shdr[elf->shdrNameIndex].offset, LE));
|
||||
|
||||
for (int i = 0; i < elf->sectionNum; i++) {
|
||||
elf->sections[i].name = nameTable + u8_to_u32(shdr[i].name, LE);
|
||||
elf->sections[i].type = u8_to_u32(shdr[i].type, LE);
|
||||
elf->sections[i].flags = u8_to_u32(shdr[i].flags, LE);
|
||||
elf->sections[i].fileOffset = u8_to_u32(shdr[i].offset, LE);
|
||||
elf->sections[i].size = u8_to_u32(shdr[i].size, LE);
|
||||
elf->sections[i].ptr = elf->file + elf->sections[i].fileOffset;
|
||||
elf->sections[i].vAddr = u8_to_u32(shdr[i].addr, LE);
|
||||
elf->sections[i].alignment = u8_to_u32(shdr[i].addralign, LE);
|
||||
}
|
||||
}
|
||||
|
||||
void elf_PopulateSegments(elf_context *elf)
|
||||
{
|
||||
const elf_phdr *phdr = (const elf_phdr *)(elf->file + elf->phdrOffset);
|
||||
|
||||
for (int i = 0; i < elf->segmentNum; i++) {
|
||||
elf->segments[i].type = u8_to_u32(phdr[i].type, LE);
|
||||
elf->segments[i].flags = u8_to_u32(phdr[i].flags, LE);
|
||||
elf->segments[i].fileOffset = u8_to_u32(phdr[i].offset, LE);
|
||||
elf->segments[i].fileSize = u8_to_u32(phdr[i].filesz, LE);
|
||||
elf->segments[i].ptr = elf->file + elf->segments[i].fileOffset;
|
||||
elf->segments[i].pAddr = u8_to_u32(phdr[i].paddr, LE);
|
||||
elf->segments[i].vAddr = u8_to_u32(phdr[i].vaddr, LE);
|
||||
elf->segments[i].memSize = u8_to_u32(phdr[i].memsz, LE);
|
||||
elf->segments[i].alignment = u8_to_u32(phdr[i].align, LE);
|
||||
}
|
||||
}
|
||||
|
||||
int elf_Init(elf_context *elf, const u8 *elfFile)
|
||||
{
|
||||
elf->file = elfFile;
|
||||
|
||||
int result;
|
||||
|
||||
if((result = elf_ProcessHeader(elf))) return result;
|
||||
|
||||
elf_PopulateSections(elf);
|
||||
elf_PopulateSegments(elf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void elf_Free(elf_context *elf)
|
||||
{
|
||||
free(elf->sections);
|
||||
free(elf->segments);
|
||||
memset(elf, 0, sizeof(elf_context));
|
||||
}
|
||||
|
||||
u16 elf_SectionNum(elf_context *ctx)
|
||||
{
|
||||
return ctx->sectionNum;
|
||||
}
|
||||
|
||||
const elf_section* elf_GetSections(elf_context *ctx)
|
||||
{
|
||||
return ctx->sections;
|
||||
}
|
||||
|
||||
u16 elf_SegmentNum(elf_context *ctx)
|
||||
{
|
||||
return ctx->segmentNum;
|
||||
}
|
||||
|
||||
const elf_segment* elf_GetSegments(elf_context *ctx)
|
||||
{
|
||||
return ctx->segments;
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum elf_errors
|
||||
{
|
||||
NOT_ELF_FILE = -10,
|
||||
NOT_CTR_ARM_ELF = -11,
|
||||
NON_EXECUTABLE_ELF = -12,
|
||||
ELF_SECTION_NOT_FOUND = -13,
|
||||
NOT_FIND_TEXT_SEGMENT = -14,
|
||||
NOT_FIND_DATA_SEGMENT = -15,
|
||||
ELF_SEGMENT_SECTION_SIZE_MISMATCH = -16,
|
||||
ELF_SEGMENTS_NOT_CONTINUOUS = -17,
|
||||
ELF_SEGMENTS_NOT_FOUND = -18,
|
||||
} elf_errors;
|
||||
|
||||
typedef enum elf_section_type
|
||||
{
|
||||
SHT_NULL,
|
||||
SHT_PROGBITS,
|
||||
SHT_SYMTAB,
|
||||
SHT_STRTAB,
|
||||
SHT_RELA,
|
||||
SHT_HASH,
|
||||
SHT_DYNAMIC,
|
||||
SHT_NOTE,
|
||||
SHT_NOBITS,
|
||||
SHT_REL,
|
||||
SHT_SHLIB,
|
||||
SHT_DYNSYM,
|
||||
SHT_UNKNOWN12,
|
||||
SHT_UNKNOWN13,
|
||||
SHT_INIT_ARRAY,
|
||||
SHT_FINI_ARRAY,
|
||||
SHT_PREINIT_ARRAY,
|
||||
SHT_GROUP,
|
||||
SHT_SYMTAB_SHNDX,
|
||||
SHT_NUM,
|
||||
SHT_ARM_EXIDX = 0x70000001,
|
||||
SHT_ARM_PREEMPTMAP,
|
||||
SHT_ARM_ATTRIBUTES,
|
||||
SHT_ARM_DEBUGOVERLAY,
|
||||
SHT_ARM_OVERLAYSECTION
|
||||
} elf_section_type;
|
||||
|
||||
typedef enum elf_section_flag
|
||||
{
|
||||
SHF_WRITE = 0x1,
|
||||
SHF_ALLOC = 0x2,
|
||||
SHF_EXECINSTR = 0x4,
|
||||
SHF_MERGE = 0x10,
|
||||
SHF_STRINGS = 0x20,
|
||||
SHF_INFO_LINK = 0x40,
|
||||
SHF_LINK_ORDER = 0x80,
|
||||
SHF_OS_NONCONFORMING = 0x100,
|
||||
SHF_GROUP = 0x200,
|
||||
SHF_TLS = 0x400
|
||||
} elf_section_flag;
|
||||
|
||||
typedef struct elf_section
|
||||
{
|
||||
const char *name;
|
||||
u32 type;
|
||||
u32 flags;
|
||||
const u8 *ptr;
|
||||
u32 fileOffset;
|
||||
u32 size;
|
||||
u32 vAddr;
|
||||
u32 alignment;
|
||||
} elf_section;
|
||||
|
||||
typedef enum elf_program_type
|
||||
{
|
||||
PT_NULL,
|
||||
PT_LOAD,
|
||||
PT_DYNAMIC,
|
||||
PT_INTERP,
|
||||
PT_NOTE,
|
||||
PT_SHLIB,
|
||||
PT_PHDR,
|
||||
} elf_program_type;
|
||||
|
||||
typedef enum elf_program_flag
|
||||
{
|
||||
PF_X = 0x1,
|
||||
PF_W = 0x2,
|
||||
PF_R = 0x4,
|
||||
PF_CTRSDK = 0x80000000,
|
||||
|
||||
PF_TEXT = (PF_R|PF_X),
|
||||
PF_DATA = (PF_R|PF_W),
|
||||
PF_RODATA = PF_R
|
||||
} elf_program_flag;
|
||||
|
||||
typedef struct elf_segment
|
||||
{
|
||||
u32 type;
|
||||
u32 flags;
|
||||
const u8 *ptr;
|
||||
u32 fileOffset;
|
||||
u32 fileSize;
|
||||
u32 memSize;
|
||||
u32 vAddr;
|
||||
u32 pAddr;
|
||||
u32 alignment;
|
||||
} elf_segment;
|
||||
|
||||
typedef struct elf_context
|
||||
{
|
||||
const u8 *file;
|
||||
|
||||
u32 shdrOffset;
|
||||
u16 shdrNameIndex;
|
||||
u32 phdrOffset;
|
||||
|
||||
u16 sectionNum;
|
||||
elf_section *sections;
|
||||
|
||||
u16 segmentNum;
|
||||
elf_segment *segments;
|
||||
} elf_context;
|
||||
|
||||
|
||||
int elf_Init(elf_context *ctx, const u8 *fp);
|
||||
void elf_Free(elf_context *ctx);
|
||||
|
||||
u16 elf_SectionNum(elf_context *ctx);
|
||||
const elf_section* elf_GetSections(elf_context *ctx);
|
||||
|
||||
u16 elf_SegmentNum(elf_context *ctx);
|
||||
const elf_segment* elf_GetSegments(elf_context *ctx);
|
||||
@@ -0,0 +1,179 @@
|
||||
#include "lib.h"
|
||||
#include "ncch_build.h"
|
||||
#include "exefs_build.h"
|
||||
|
||||
// Private Prototypes
|
||||
u32 PredictExeFS_Size(exefs_buildctx *ctx);
|
||||
int GenerateExeFS_Header(exefs_buildctx *ctx, u8 *outbuff);
|
||||
void FreeExeFSContext(exefs_buildctx *ctx);
|
||||
int ImportDatatoExeFS(exefs_buildctx *ctx, u8 *outbuff);
|
||||
int ImportToExeFSContext(exefs_buildctx *ctx, char *name, u8 *buffer, u32 size);
|
||||
|
||||
// ExeFs Build Functions
|
||||
int BuildExeFs(ncch_settings *ncchset)
|
||||
{
|
||||
/* Intialising ExeFs Build Context */
|
||||
exefs_buildctx *ctx = calloc(1,sizeof(exefs_buildctx));
|
||||
if(!ctx) {
|
||||
fprintf(stderr,"[EXEFS ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
ctx->blockSize = ncchset->options.blockSize;
|
||||
|
||||
/* Importing ExeFs */
|
||||
if(ncchset->exefsSections.code.size)
|
||||
ImportToExeFSContext(ctx,".code",ncchset->exefsSections.code.buffer,ncchset->exefsSections.code.size);
|
||||
if(ncchset->exefsSections.banner.size)
|
||||
ImportToExeFSContext(ctx,"banner",ncchset->exefsSections.banner.buffer,ncchset->exefsSections.banner.size);
|
||||
if(ncchset->exefsSections.icon.size)
|
||||
ImportToExeFSContext(ctx,"icon",ncchset->exefsSections.icon.buffer,ncchset->exefsSections.icon.size);
|
||||
if(ncchset->sections.logo.size && ncchset->options.IncludeExeFsLogo)
|
||||
ImportToExeFSContext(ctx,"logo",ncchset->sections.logo.buffer,ncchset->sections.logo.size);
|
||||
|
||||
if(ctx->fileCount == 0){ // no exefs needed
|
||||
ncchset->sections.exeFs.size = 0;
|
||||
ncchset->sections.exeFs.buffer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocating Memory for ExeFs */
|
||||
ncchset->sections.exeFs.size = PredictExeFS_Size(ctx);
|
||||
ncchset->sections.exeFs.buffer = malloc(ncchset->sections.exeFs.size);
|
||||
if(!ncchset->sections.exeFs.buffer){
|
||||
printf("[EXEFS ERROR] Could Not Allocate Memory for ExeFS\n");
|
||||
return Fail;
|
||||
}
|
||||
memset(ncchset->sections.exeFs.buffer,0,ncchset->sections.exeFs.size);
|
||||
|
||||
/* Generating Header, and writing sections to buffer */
|
||||
GenerateExeFS_Header(ctx,ncchset->sections.exeFs.buffer);
|
||||
ImportDatatoExeFS(ctx,ncchset->sections.exeFs.buffer);
|
||||
|
||||
/* Finish */
|
||||
FreeExeFSContext(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 PredictExeFS_Size(exefs_buildctx *ctx)
|
||||
{
|
||||
u32 exefs_size = sizeof(exefs_hdr); // Size of header
|
||||
for(int i = 0; i < ctx->fileCount; i++)
|
||||
exefs_size += align(ctx->fileSize[i],ctx->blockSize);
|
||||
//exefs_size = align(ctx->exefs_size,ctx->mediaUnit);
|
||||
return exefs_size;
|
||||
}
|
||||
|
||||
int GenerateExeFS_Header(exefs_buildctx *ctx, u8 *outbuff)
|
||||
{
|
||||
exefs_hdr *exefs = (exefs_hdr*)outbuff;
|
||||
for(int i = 0; i < ctx->fileCount; i++){
|
||||
if(i == 0)
|
||||
ctx->fileOffset[i] = 0;
|
||||
else
|
||||
ctx->fileOffset[i] = align((ctx->fileOffset[i-1]+ctx->fileSize[i-1]),ctx->blockSize);
|
||||
|
||||
memcpy(exefs->fileHdr[i].name,ctx->fileName[i],8);
|
||||
u32_to_u8(exefs->fileHdr[i].offset,ctx->fileOffset[i],LE);
|
||||
u32_to_u8(exefs->fileHdr[i].size,ctx->fileSize[i],LE);
|
||||
ShaCalc(ctx->file[i],ctx->fileSize[i],exefs->fileHashes[MAX_EXEFS_SECTIONS-1-i],CTR_SHA_256);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FreeExeFSContext(exefs_buildctx *ctx)
|
||||
{
|
||||
/*
|
||||
if(ctx->outbuff != NULL)
|
||||
free(ctx->outbuff);
|
||||
for(int i = 0; i < 10; i++){
|
||||
if(ctx->file[i] != NULL)
|
||||
free(ctx->file[i]);
|
||||
}
|
||||
*/
|
||||
memset(ctx,0,sizeof(exefs_buildctx));
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
int ImportDatatoExeFS(exefs_buildctx *ctx, u8 *outbuff)
|
||||
{
|
||||
for(int i = 0; i < ctx->fileCount; i++){
|
||||
memcpy(outbuff+ctx->fileOffset[i]+0x200,ctx->file[i],ctx->fileSize[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ImportToExeFSContext(exefs_buildctx *ctx, char *name, u8 *buffer, u32 size)
|
||||
{
|
||||
if(ctx == NULL || name == NULL || buffer == NULL){
|
||||
printf("[!] PTR ERROR\n");
|
||||
return PTR_ERROR;
|
||||
}
|
||||
if(ctx->fileCount >= MAX_EXEFS_SECTIONS){
|
||||
printf("[!] Maximum ExeFS Capacity Reached\n");
|
||||
return EXEFS_MAX_REACHED;
|
||||
}
|
||||
if(strlen(name) > 8){
|
||||
printf("[!] ExeFS File Name: '%s' is too large\n",name);
|
||||
return EXEFS_SECTION_NAME_ERROR;
|
||||
}
|
||||
|
||||
ctx->fileCount++;
|
||||
ctx->file[ctx->fileCount - 1] = buffer;
|
||||
ctx->fileSize[ctx->fileCount - 1] = size;
|
||||
strcpy(ctx->fileName[ctx->fileCount - 1],name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ExeFs Read Functions
|
||||
bool DoesExeFsSectionExist(char *section, u8 *ExeFs)
|
||||
{
|
||||
exefs_hdr *hdr = (exefs_hdr*) ExeFs;
|
||||
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
|
||||
if(strncmp(hdr->fileHdr[i].name,section,8) == 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
u8* GetExeFsSection(char *section, u8 *ExeFs)
|
||||
{
|
||||
exefs_hdr *hdr = (exefs_hdr*) ExeFs;
|
||||
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
|
||||
if(strncmp(hdr->fileHdr[i].name,section,8) == 0){
|
||||
u32 offset = u8_to_u32(hdr->fileHdr[i].offset,LE) + sizeof(exefs_hdr);
|
||||
return (u8*)(ExeFs+offset);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8* GetExeFsSectionHash(char *section, u8 *ExeFs)
|
||||
{
|
||||
exefs_hdr *hdr = (exefs_hdr*) ExeFs;
|
||||
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
|
||||
if(strncmp(hdr->fileHdr[i].name,section,8) == 0){
|
||||
return (u8*)(hdr->fileHashes[MAX_EXEFS_SECTIONS-1-i]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u32 GetExeFsSectionSize(char *section, u8 *ExeFs)
|
||||
{
|
||||
exefs_hdr *hdr = (exefs_hdr*) ExeFs;
|
||||
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
|
||||
if(strncmp(hdr->fileHdr[i].name,section,8) == 0){
|
||||
return u8_to_u32(hdr->fileHdr[i].size,LE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 GetExeFsSectionOffset(char *section, u8 *ExeFs)
|
||||
{
|
||||
exefs_hdr *hdr = (exefs_hdr*) ExeFs;
|
||||
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
|
||||
if(strncmp(hdr->fileHdr[i].name,section,8) == 0){
|
||||
return u8_to_u32(hdr->fileHdr[i].offset,LE) + sizeof(exefs_hdr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#define MAX_EXEFS_SECTIONS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[8];
|
||||
u8 offset[4];
|
||||
u8 size[4];
|
||||
} exefs_filehdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
exefs_filehdr fileHdr[MAX_EXEFS_SECTIONS];
|
||||
u8 reserved[0x80];
|
||||
u8 fileHashes[MAX_EXEFS_SECTIONS][0x20];
|
||||
} exefs_hdr;
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "exefs.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PTR_ERROR = -10,
|
||||
EXEFS_MAX_REACHED = -11,
|
||||
EXEFS_SECTION_NAME_ERROR = -12,
|
||||
} exefs_errors;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//Input
|
||||
int fileCount;
|
||||
u8 *file[MAX_EXEFS_SECTIONS];
|
||||
u32 fileSize[MAX_EXEFS_SECTIONS];
|
||||
u32 fileOffset[MAX_EXEFS_SECTIONS];
|
||||
char fileName[MAX_EXEFS_SECTIONS][8];
|
||||
u32 blockSize;
|
||||
|
||||
//Working Data
|
||||
exefs_filehdr fileHdr[MAX_EXEFS_SECTIONS];
|
||||
u8 fileHashes[MAX_EXEFS_SECTIONS][0x20];
|
||||
|
||||
} exefs_buildctx;
|
||||
|
||||
/* ExeFs Build Functions */
|
||||
int BuildExeFs(ncch_settings *ncchset);
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "exefs.h"
|
||||
|
||||
/* ExeFs Read Functions */
|
||||
bool DoesExeFsSectionExist(char *section, u8 *ExeFs);
|
||||
u8* GetExeFsSection(char *section, u8 *ExeFs);
|
||||
u8* GetExeFsSectionHash(char *section, u8 *ExeFs);
|
||||
u32 GetExeFsSectionSize(char *section, u8 *ExeFs);
|
||||
u32 GetExeFsSectionOffset(char *section, u8 *ExeFs);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,248 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum
|
||||
{
|
||||
infoflag_COMPRESS_EXEFS_0 = 1,
|
||||
infoflag_SD_APPLICATION = 2,
|
||||
} system_info_flags;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
sysmode_64MB, // prod
|
||||
sysmode_UNK, // null
|
||||
sysmode_96MB, // dev1
|
||||
sysmode_80MB, // dev2
|
||||
sysmode_72MB, // dev3
|
||||
sysmode_32MB, // dev4
|
||||
} system_mode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
sysmode_ext_LEGACY,
|
||||
sysmode_ext_124MB, // snake Prod
|
||||
sysmode_ext_178MB, // snake Dev1
|
||||
} system_mode_ext;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
memtype_APPLICATION = 1,
|
||||
memtype_SYSTEM = 2,
|
||||
memtype_BASE = 3
|
||||
} memory_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
processtype_DEFAULT = -1,
|
||||
processtype_SYSTEM = 0,
|
||||
processtype_APPLICATION = 1
|
||||
} process_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
resrc_limit_APPLICATION,
|
||||
resrc_limit_SYS_APPLET,
|
||||
resrc_limit_LIB_APPLET,
|
||||
resrc_limit_OTHER
|
||||
} resource_limit_category;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
cpuspeed_268MHz,
|
||||
cpuspeed_804MHz
|
||||
} cpu_speed;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
othcap_PERMIT_DEBUG = (1 << 0),
|
||||
othcap_FORCE_DEBUG = (1 << 1),
|
||||
othcap_CAN_USE_NON_ALPHABET_AND_NUMBER = (1 << 2),
|
||||
othcap_CAN_WRITE_SHARED_PAGE = (1 << 3),
|
||||
othcap_CAN_USE_PRIVILEGE_PRIORITY = (1 << 4),
|
||||
othcap_PERMIT_MAIN_FUNCTION_ARGUMENT = (1 << 5),
|
||||
othcap_CAN_SHARE_DEVICE_MEMORY = (1 << 6),
|
||||
othcap_RUNNABLE_ON_SLEEP = (1 << 7),
|
||||
othcap_SPECIAL_MEMORY_ARRANGE = (1 << 12),
|
||||
othcap_CAN_ACCESS_CORE2 = (1 << 13),
|
||||
} other_capabilities_flags;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
fsaccess_CATEGORY_SYSTEM_APPLICATION = (1 << 0), // 0x00000001 used by all sys apps?
|
||||
fsaccess_CATEGORY_HARDWARE_CHECK = (1 << 1), // 0x00000002
|
||||
fsaccess_CATEGORY_FILE_SYSTEM_TOOL = (1 << 2), // 0x00000004
|
||||
fsaccess_DEBUG = (1 << 3), // 0x00000008
|
||||
fsaccess_TWL_CARD_BACKUP = (1 << 4), // 0x00000010
|
||||
fsaccess_TWL_NAND_DATA = (1 << 5), // 0x00000020
|
||||
fsaccess_BOSS = (1 << 6), // 0x00000040
|
||||
fsaccess_DIRECT_SDMC = (1 << 7), // 0x00000080
|
||||
fsaccess_CORE = (1 << 8), // 0x00000100
|
||||
fsaccess_CTR_NAND_RO = (1 << 9), // 0x00000200
|
||||
fsaccess_CTR_NAND_RW = (1 << 10), // 0x00000400
|
||||
fsaccess_CTR_NAND_RO_WRITE = (1 << 11), // 0x00000800
|
||||
fsaccess_CATEGORY_SYSTEM_SETTINGS = (1 << 12), // 0x00001000
|
||||
fsaccess_CARD_BOARD = (1 << 13), // 0x00002000 probably used by sys transfer
|
||||
fsaccess_EXPORT_IMPORT_IVS = (1 << 14), // 0x00004000
|
||||
fsaccess_DIRECT_SDMC_WRITE = (1 << 15), // 0x00008000
|
||||
fsaccess_SWITCH_CLEANUP = (1 << 16), // 0x00010000 reference to Sys Transfer?
|
||||
fsaccess_SAVE_DATA_MOVE = (1 << 17), // 0x00020000 used by save transfer tool
|
||||
fsaccess_SHOP = (1 << 18), // 0x00040000 probably used by eshop
|
||||
fsaccess_SHELL = (1 << 19), // 0x00080000 reference to "Nintendo [User Interface] Shell" (NS)?
|
||||
fsaccess_CATEGORY_HOME_MENU = (1 << 20), // 0x00100000 used by homemenu
|
||||
fsaccess_SEEDDB = (1 << 21), // 0x00200000 seeddb access
|
||||
} file_system_access;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
attribute_NOT_USE_ROMFS = (1 << 0),
|
||||
attribute_USE_EXTENDED_SAVEDATA_ACCESS_CONTROL = (1 << 1),
|
||||
} attribute_name;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
arm9cap_FS_MOUNT_NAND = (1 << 0),
|
||||
arm9cap_FS_MOUNT_NAND_RO_WRITE = (1 << 1),
|
||||
arm9cap_FS_MOUNT_TWLN = (1 << 2),
|
||||
arm9cap_FS_MOUNT_WNAND = (1 << 3),
|
||||
arm9cap_FS_MOUNT_CARD_SPI = (1 << 4),
|
||||
arm9cap_USE_SDIF3 = (1 << 5),
|
||||
arm9cap_CREATE_SEED = (1 << 6),
|
||||
arm9cap_USE_CARD_SPI = (1 << 7),
|
||||
arm9cap_SD_APPLICATION = (1 << 8),
|
||||
arm9cap_USE_DIRECT_SDMC = (1 << 9),
|
||||
} arm9_capability;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 address[4]; // le u32
|
||||
u8 numMaxPages[4]; // le u32
|
||||
u8 codeSize[4]; // le u32
|
||||
} exhdr_CodeSegmentInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 name[8];
|
||||
u8 padding0[5];
|
||||
union {
|
||||
u8 flag;
|
||||
struct {
|
||||
u8 compressExeFs0 : 1;
|
||||
u8 useOnSd : 1;
|
||||
};
|
||||
};
|
||||
|
||||
u8 remasterVersion[2]; // le u16
|
||||
exhdr_CodeSegmentInfo text;
|
||||
u8 stackSize[4]; // le u32
|
||||
exhdr_CodeSegmentInfo rodata;
|
||||
u8 padding1[4];
|
||||
exhdr_CodeSegmentInfo data;
|
||||
u8 bssSize[4]; // le u32
|
||||
} exhdr_CodeSetInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 savedataSize[8];
|
||||
u8 jumpId[8];
|
||||
u8 padding0[0x30];
|
||||
} exhdr_SystemInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 extSavedataId[8];
|
||||
u8 systemSavedataId[2][4];
|
||||
u8 storageAccessableUniqueIds[8];
|
||||
u8 accessInfo[7];
|
||||
u8 otherAttributes;
|
||||
} exhdr_StorageInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 programId[8];
|
||||
u8 coreVersion[4];
|
||||
union {
|
||||
u8 flag[4];
|
||||
struct {
|
||||
u8 enableL2Cache : 1;
|
||||
u8 cpuSpeed : 1;
|
||||
u8: 6;
|
||||
|
||||
u8 systemModeExt : 4;
|
||||
u8: 4;
|
||||
|
||||
u8 idealProcessor : 2;
|
||||
u8 affinityMask : 2;
|
||||
u8 systemMode : 4;
|
||||
|
||||
s8 threadPriority;
|
||||
};
|
||||
};
|
||||
u8 resourceLimitDescriptor[16][2];
|
||||
exhdr_StorageInfo storageInfo;
|
||||
u8 serviceAccessControl[34][8]; // Those char[8] server names
|
||||
u8 padding1[0xf];
|
||||
u8 resourceLimitCategory;
|
||||
} exhdr_ARM11SystemLocalCapabilities;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u16 num;
|
||||
u32 *data;
|
||||
} ARM11KernelCapabilityDescriptor;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
desc_InteruptNumList = 0xe0000000,
|
||||
desc_SysCallControl = 0xf0000000,
|
||||
desc_KernelReleaseVersion = 0xfc000000,
|
||||
desc_HandleTableSize = 0xfe000000,
|
||||
desc_OtherCapabilities = 0xff000000,
|
||||
desc_MappingStatic = 0xff800000,
|
||||
desc_MappingIO = 0xffc00000,
|
||||
} ARM11KernelCapabilityDescriptorBitmask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 descriptors[28][4];// Descripters are a collection of u32s, with bitmask idents so they can be identified, 'no matter the pos'
|
||||
u8 reserved[0x10];
|
||||
} exhdr_ARM11KernelCapabilities;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 descriptors[16]; //descriptors[15] = DescVersion
|
||||
} exhdr_ARM9AccessControlInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// systemcontrol info {
|
||||
// coreinfo {
|
||||
exhdr_CodeSetInfo codeSetInfo;
|
||||
u8 dependencyList[0x30][8];
|
||||
// }
|
||||
exhdr_SystemInfo systemInfo;
|
||||
// }
|
||||
// accesscontrolinfo {
|
||||
exhdr_ARM11SystemLocalCapabilities arm11SystemLocalCapabilities;
|
||||
exhdr_ARM11KernelCapabilities arm11KernelCapabilities;
|
||||
exhdr_ARM9AccessControlInfo arm9AccessControlInfo;
|
||||
// }
|
||||
} extended_hdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 signature[0x100];
|
||||
u8 ncchRsaPubKey[0x100];
|
||||
exhdr_ARM11SystemLocalCapabilities arm11SystemLocalCapabilities;
|
||||
exhdr_ARM11KernelCapabilities arm11KernelCapabilities;
|
||||
exhdr_ARM9AccessControlInfo arm9AccessControlInfo;
|
||||
} access_descriptor;
|
||||
|
||||
/* ExHeader Signature Functions */
|
||||
int SignAccessDesc(access_descriptor *acexDesc, keys_struct *keys);
|
||||
int CheckAccessDescSignature(access_descriptor *acexDesc, keys_struct *keys);
|
||||
|
||||
/* ExHeader Settings Read from Rsf */
|
||||
int GetSaveDataSizeFromString(u64 *out, char *string, char *moduleName);
|
||||
int GetRemasterVersion_rsf(u16 *RemasterVersion, user_settings *usrset);
|
||||
|
||||
void ErrorParamNotFound(char *string);
|
||||
void WarnParamNotFound(char *string);
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "exheader.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMMON_HEADER_KEY_NOT_FOUND = -10,
|
||||
EXHDR_BAD_RSF_OPT = -11,
|
||||
CANNOT_SIGN_ACCESSDESC = -12
|
||||
} exheader_errors;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
keys_struct *keys;
|
||||
rsf_settings *rsf;
|
||||
bool useAccessDescPreset;
|
||||
|
||||
/* Output, these ptrs where created originally in ncchset */
|
||||
extended_hdr *exHdr;
|
||||
access_descriptor *acexDesc;
|
||||
} exheader_settings;
|
||||
|
||||
/* ExHeader Build Functions */
|
||||
int BuildExHeader(ncch_settings *ncchset);
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "exheader.h"
|
||||
|
||||
/* ExHeader Binary Print Functions */
|
||||
void exhdr_Print_ServiceAccessControl(extended_hdr *hdr);
|
||||
|
||||
/* ExHeader Binary Read Functions */
|
||||
u8* GetAcexRsaSig(access_descriptor *acexDesc);
|
||||
u8* GetAcexNcchPubKey(access_descriptor *acexDesc);
|
||||
u16 GetRemasterVersion_frm_exhdr(extended_hdr *hdr);
|
||||
u64 GetSaveDataSize_frm_exhdr(extended_hdr *hdr);
|
||||
int GetDependencyList_frm_exhdr(u8 *Dest,extended_hdr *hdr);
|
||||
void GetCoreVersion_frm_exhdr(u8 *Dest, extended_hdr *hdr);
|
||||
@@ -0,0 +1,418 @@
|
||||
#include "lib.h"
|
||||
#include "aes_keygen.h"
|
||||
|
||||
// KeyData
|
||||
#include "pki/test.h" // Test PKI
|
||||
#include "pki/prod.h" // Production PKI
|
||||
#include "pki/dev.h" // Development PKI
|
||||
|
||||
// Private Prototypes
|
||||
int SetRsaKeySet(u8 **priv_exp_dst, const u8 *priv_exp_src, u8 **modulus_dst, const u8 *modulus_src);
|
||||
void InitCommonKeySlots(keys_struct *keys);
|
||||
void InitNcchKeyXSlots(keys_struct *keys);
|
||||
int SetNcchKeyX(keys_struct *keys, const u8 *keyX, u8 index);
|
||||
|
||||
void keysetOpenError(char *file);
|
||||
FILE* keyset_OpenFile(char *dir, char *name, bool FileRequired);
|
||||
|
||||
int SetCaCert(keys_struct *keys, const u8 *cert);
|
||||
int SetTikCert(keys_struct *keys, const u8 *cert);
|
||||
int SetTmdCert(keys_struct *keys, const u8 *cert);
|
||||
|
||||
int LoadKeysFromResources(keys_struct *keys);
|
||||
void SetDummyRsaData(keys_struct *keys);
|
||||
int LoadKeysFromKeyfile(keys_struct *keys);
|
||||
void DumpKeyset(keys_struct *keys);
|
||||
|
||||
|
||||
|
||||
// Code
|
||||
void InitKeys(keys_struct *keys)
|
||||
{
|
||||
memset(keys,0,sizeof(keys_struct));
|
||||
InitCommonKeySlots(keys);
|
||||
InitNcchKeyXSlots(keys);
|
||||
Rsa2048Key_Alloc(&keys->rsa.xs);
|
||||
Rsa2048Key_Alloc(&keys->rsa.cp);
|
||||
Rsa2048Key_Alloc(&keys->rsa.cciCfa);
|
||||
Rsa2048Key_Alloc(&keys->rsa.acex);
|
||||
Rsa2048Key_Alloc(&keys->rsa.cxi);
|
||||
keys->aes.ncchKey0 = malloc(AES_128_KEY_SIZE);
|
||||
keys->aes.ncchKey1 = malloc(AES_128_KEY_SIZE);
|
||||
}
|
||||
|
||||
void PrintBadKeySize(char *path, u32 size)
|
||||
{
|
||||
fprintf(stderr,"[KEYSET ERROR] %s has invalid size (0x%x)\n",path,size);
|
||||
}
|
||||
|
||||
int SetKeys(keys_struct *keys)
|
||||
{
|
||||
if (LoadKeysFromResources(keys) != 0)
|
||||
{
|
||||
return KEYSET_ERROR;
|
||||
}
|
||||
|
||||
if (!keys->keysetLoaded)
|
||||
{
|
||||
return KEYSET_ERROR;
|
||||
}
|
||||
|
||||
if (keys->dumpkeys)
|
||||
{
|
||||
DumpKeyset(keys);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LoadKeysFromResources(keys_struct *keys)
|
||||
{
|
||||
if(keys->keyset == pki_TEST){
|
||||
keys->keysetLoaded = true;
|
||||
/* AES Keys */
|
||||
// CIA
|
||||
//SetCommonKey(keys, zeros_aesKey,1);
|
||||
if(keys->aes.currentCommonKey > MAX_CMN_KEY)
|
||||
SetCurrentCommonKey(keys,0);
|
||||
|
||||
// NCCH
|
||||
SetNormalKey(keys,zeros_aesKey);
|
||||
SetSystemFixedKey(keys,zeros_aesKey);
|
||||
|
||||
// CCI
|
||||
SetCciInitialDataKeyX(keys, zeros_aesKey);
|
||||
|
||||
/* RSA Keys */
|
||||
// CIA
|
||||
Rsa2048Key_Set(&keys->rsa.xs, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.cp, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
// CCI/CFA
|
||||
Rsa2048Key_Set(&keys->rsa.cciCfa, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
// CXI
|
||||
Rsa2048Key_Set(&keys->rsa.acex, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
|
||||
/* Certs */
|
||||
SetCaCert(keys, ca3_tpki_cert);
|
||||
SetTikCert(keys, xsC_tpki_cert);
|
||||
SetTmdCert(keys, cpB_tpki_cert);
|
||||
}
|
||||
else if(keys->keyset == pki_DEVELOPMENT){
|
||||
keys->keysetLoaded = true;
|
||||
/* AES Keys */
|
||||
// CIA
|
||||
for(int i = 0; i < 6; i++)
|
||||
SetCommonKey(keys, ctr_common_etd_key_dpki[i],i);
|
||||
|
||||
if(keys->aes.currentCommonKey > MAX_CMN_KEY)
|
||||
SetCurrentCommonKey(keys,0);
|
||||
|
||||
// NCCH
|
||||
SetNormalKey(keys, dev_fixed_ncch_key[0]);
|
||||
SetSystemFixedKey(keys, dev_fixed_ncch_key[1]);
|
||||
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
SetNcchKeyX(keys, dev_unfixed_ncch_keyX[i],i);
|
||||
|
||||
// CCI
|
||||
SetCciInitialDataKeyX(keys, dev_initial_data_keyx);
|
||||
|
||||
/* RSA Keys */
|
||||
// CIA
|
||||
Rsa2048Key_Set(&keys->rsa.xs, xs9_dpki_rsa.priv_exponent, xs9_dpki_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.cp, cpA_dpki_rsa.priv_exponent, cpA_dpki_rsa.modulus);
|
||||
// CCI/CFA
|
||||
Rsa2048Key_Set(&keys->rsa.cciCfa, dev_ncsd_cfa_rsa.priv_exponent, dev_ncsd_cfa_rsa.modulus);
|
||||
// CXI
|
||||
Rsa2048Key_Set(&keys->rsa.acex, dev_accessdesc_rsa.priv_exponent, dev_accessdesc_rsa.modulus);
|
||||
|
||||
/* Certs */
|
||||
SetCaCert(keys, ca4_dpki_cert);
|
||||
SetTikCert(keys, xs9_dpki_cert);
|
||||
SetTmdCert(keys, cpA_dpki_cert);
|
||||
}
|
||||
else if(keys->keyset == pki_PRODUCTION){
|
||||
keys->keysetLoaded = true;
|
||||
/* AES Keys */
|
||||
// CIA
|
||||
for (int i = 0; i < 6; i++)
|
||||
SetCommonKey(keys, ctr_common_etd_key_ppki[i], i);
|
||||
|
||||
if(keys->aes.currentCommonKey > MAX_CMN_KEY)
|
||||
SetCurrentCommonKey(keys,0);
|
||||
|
||||
// NCCH
|
||||
keys->aes.normalKey = NULL;
|
||||
keys->aes.systemFixedKey = NULL;
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
SetNcchKeyX(keys, prod_unfixed_ncch_keyX[i],i);
|
||||
|
||||
// CCI
|
||||
SetCciInitialDataKeyX(keys, dev_initial_data_keyx);
|
||||
|
||||
/* RSA Keys */
|
||||
// CIA
|
||||
Rsa2048Key_Set(&keys->rsa.xs, xsC_ppki_rsa.priv_exponent, xsC_ppki_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.cp, cpB_ppki_rsa.priv_exponent, cpB_ppki_rsa.modulus);
|
||||
// CCI/CFA
|
||||
Rsa2048Key_Set(&keys->rsa.cciCfa, prod_ncsd_cfa_rsa.priv_exponent, prod_ncsd_cfa_rsa.modulus);
|
||||
// CXI
|
||||
Rsa2048Key_Set(&keys->rsa.acex, prod_accessdesc_rsa.priv_exponent, prod_accessdesc_rsa.modulus);
|
||||
|
||||
/* Certs */
|
||||
SetCaCert(keys, ca3_ppki_cert);
|
||||
SetTikCert(keys, xsC_ppki_cert);
|
||||
SetTmdCert(keys, cpB_ppki_cert);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void SetDummyRsaData(keys_struct *keys)
|
||||
{
|
||||
// CIA
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.xs) == false)
|
||||
Rsa2048Key_Set(&keys->rsa.xs, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.cp) == false)
|
||||
Rsa2048Key_Set(&keys->rsa.cp, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
// CCI/CFA
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.cciCfa) == false)
|
||||
Rsa2048Key_Set(&keys->rsa.cciCfa, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
// CXI
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.acex) == false)
|
||||
Rsa2048Key_Set(&keys->rsa.acex, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
|
||||
// Certs
|
||||
if(!keys->certs.caCert)
|
||||
SetCaCert(keys, ca3_tpki_cert);
|
||||
if(!keys->certs.xsCert)
|
||||
SetTikCert(keys, xsC_tpki_cert);
|
||||
if(!keys->certs.cpCert)
|
||||
SetTmdCert(keys, cpB_tpki_cert);
|
||||
}
|
||||
*/
|
||||
|
||||
void DumpKeyset(keys_struct *keys)
|
||||
{
|
||||
bool showNcchFixedKeys = (keys->aes.normalKey || keys->aes.systemFixedKey);
|
||||
bool showCommonKeys = false;
|
||||
bool showNcchKeyXs = false;
|
||||
for(int i = 0; i < 256; i++){
|
||||
if(keys->aes.commonKey[i]){
|
||||
showCommonKeys = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (keys->aes.ncchKeyX[i]) {
|
||||
showNcchKeyXs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("[*] Keyset\n");
|
||||
|
||||
if(showCommonKeys){
|
||||
printf(" > eTicket Common Keys\n");
|
||||
for(int i = 0; i < 256; i++){
|
||||
if(keys->aes.commonKey[i]){
|
||||
printf(" [0x%02x] ",i);
|
||||
memdump(stdout,"",keys->aes.commonKey[i],16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showNcchKeyXs) {
|
||||
printf(" > Unfixed NCCH KeyXs\n");
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (keys->aes.ncchKeyX[i]) {
|
||||
printf(" [0x%02x] ", i);
|
||||
memdump(stdout, "", keys->aes.ncchKeyX[i], 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(showNcchFixedKeys){
|
||||
printf(" > Fixed NCCH Keys\n");
|
||||
if(keys->aes.normalKey)
|
||||
memdump(stdout," [Normal] ",keys->aes.normalKey,16);
|
||||
if(keys->aes.systemFixedKey)
|
||||
memdump(stdout," [System] ",keys->aes.systemFixedKey,16);
|
||||
}
|
||||
|
||||
printf(" > TIK RSA Keys\n");
|
||||
memdump(stdout," [PUB] ",keys->rsa.xs.pub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.xs.pvt,0x100);
|
||||
printf(" > TMD RSA Keys\n");
|
||||
memdump(stdout," [PUB] ",keys->rsa.cp.pub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.cp.pvt,0x100);
|
||||
printf(" > AcexDesc RSA Keys\n");
|
||||
memdump(stdout," [PUB] ",keys->rsa.acex.pub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.acex.pvt,0x100);
|
||||
printf(" > NcsdCfa RSA Keys\n");
|
||||
memdump(stdout," [PUB] ",keys->rsa.cciCfa.pub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.cciCfa.pvt,0x100);
|
||||
}
|
||||
|
||||
void keysetOpenError(char *file)
|
||||
{
|
||||
fprintf(stderr, "[KEYSET ERROR] Failed to open: %s\n", file);
|
||||
}
|
||||
|
||||
FILE* keyset_OpenFile(char *dir, char *name, bool is_required)
|
||||
{
|
||||
int file_path_len = sizeof(char)*(strlen(dir)+strlen(name)+1);
|
||||
char *file_path = malloc(file_path_len);
|
||||
memset(file_path,0,file_path_len);
|
||||
|
||||
sprintf(file_path,"%s%s",dir,name);
|
||||
|
||||
FILE *fp = fopen(file_path,"rb");
|
||||
|
||||
if (!fp && is_required)
|
||||
keysetOpenError(file_path);
|
||||
|
||||
free(file_path);
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FreeKeys(keys_struct *keys)
|
||||
{
|
||||
// AES
|
||||
if(keys->aes.commonKey){
|
||||
for(int i = 0; i <= MAX_CMN_KEY; i++)
|
||||
free(keys->aes.commonKey[i]);
|
||||
}
|
||||
free(keys->aes.commonKey);
|
||||
free(keys->aes.normalKey);
|
||||
free(keys->aes.systemFixedKey);
|
||||
if(keys->aes.ncchKeyX){
|
||||
for(int i = 0; i <= MAX_NCCH_KEYX; i++)
|
||||
free(keys->aes.ncchKeyX[i]);
|
||||
}
|
||||
free(keys->aes.ncchKeyX);
|
||||
free(keys->aes.ncchKey0);
|
||||
free(keys->aes.ncchKey1);
|
||||
|
||||
// RSA
|
||||
Rsa2048Key_Free(&keys->rsa.xs);
|
||||
Rsa2048Key_Free(&keys->rsa.cp);
|
||||
Rsa2048Key_Free(&keys->rsa.cciCfa);
|
||||
Rsa2048Key_Free(&keys->rsa.acex);
|
||||
Rsa2048Key_Free(&keys->rsa.cxi);
|
||||
|
||||
// Certs
|
||||
free(keys->certs.caCert);
|
||||
free(keys->certs.xsCert);
|
||||
free(keys->certs.cpCert);
|
||||
memset(keys,0,sizeof(keys_struct));
|
||||
}
|
||||
|
||||
int SetRsaKeySet(u8 **priv_exp_dst, const u8 *priv_exp_src, u8 **modulus_dst, const u8 *modulus_src)
|
||||
{
|
||||
int result = 0;
|
||||
if(priv_exp_src){
|
||||
result = CopyData(priv_exp_dst,priv_exp_src,0x100);
|
||||
if(result) return result;
|
||||
}
|
||||
if(modulus_src){
|
||||
result = CopyData(modulus_dst,modulus_src,0x100);
|
||||
if(result) return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetCommonKey(keys_struct *keys, const u8 *key, u8 index)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return CopyData(&keys->aes.commonKey[index],key,AES_128_KEY_SIZE);
|
||||
}
|
||||
|
||||
void InitCommonKeySlots(keys_struct *keys)
|
||||
{
|
||||
if(!keys->aes.commonKey)
|
||||
keys->aes.commonKey = calloc(MAX_CMN_KEY+1,sizeof(u8*));
|
||||
}
|
||||
|
||||
int SetNcchKeyX(keys_struct *keys, const u8 *keyX, u8 index)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return CopyData(&keys->aes.ncchKeyX[index],keyX,AES_128_KEY_SIZE);
|
||||
}
|
||||
|
||||
void InitNcchKeyXSlots(keys_struct *keys)
|
||||
{
|
||||
if(!keys->aes.ncchKeyX)
|
||||
keys->aes.ncchKeyX = calloc(MAX_NCCH_KEYX+1,sizeof(u8*));
|
||||
}
|
||||
|
||||
int SetCurrentCommonKey(keys_struct *keys, u8 Index)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
keys->aes.currentCommonKey = Index;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetNormalKey(keys_struct *keys, const u8 *key)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return CopyData(&keys->aes.normalKey,key,16);
|
||||
}
|
||||
|
||||
int SetSystemFixedKey(keys_struct *keys, const u8 *key)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return CopyData(&keys->aes.systemFixedKey,key,16);
|
||||
}
|
||||
|
||||
int SetCciInitialDataKeyX(keys_struct *keys, const u8 *key)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return CopyData(&keys->aes.initialDataKeyX,key,16);
|
||||
}
|
||||
|
||||
int SetCaCert(keys_struct *keys, const u8 *cert)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return CopyData(&keys->certs.caCert,cert,0x400);
|
||||
}
|
||||
int SetTikCert(keys_struct *keys, const u8 *cert)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return CopyData(&keys->certs.xsCert,cert,0x300);
|
||||
}
|
||||
|
||||
int SetTmdCert(keys_struct *keys, const u8 *cert)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return CopyData(&keys->certs.cpCert,cert,0x400);
|
||||
}
|
||||
|
||||
void Rsa2048Key_Alloc(rsa2048_key* key)
|
||||
{
|
||||
key->pub = malloc(RSA_2048_KEY_SIZE);
|
||||
key->pvt = malloc(RSA_2048_KEY_SIZE);
|
||||
}
|
||||
|
||||
void Rsa2048Key_Free(rsa2048_key* key)
|
||||
{
|
||||
free(key->pub);
|
||||
free(key->pvt);
|
||||
}
|
||||
|
||||
void Rsa2048Key_Set(rsa2048_key* key, const u8* pvt, const u8* pub)
|
||||
{
|
||||
memcpy(key->pub, pub, RSA_2048_KEY_SIZE);
|
||||
memcpy(key->pvt, pvt, RSA_2048_KEY_SIZE);
|
||||
}
|
||||
|
||||
bool Rsa2048Key_CanSign(const rsa2048_key* key)
|
||||
{
|
||||
static const u8 rsa2048[RSA_2048_KEY_SIZE] = { 0 };
|
||||
return memcmp(key->pub, rsa2048, RSA_2048_KEY_SIZE) != 0 && memcmp(key->pvt, rsa2048, RSA_2048_KEY_SIZE) != 0;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
#include "desc/desc.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AES_128_KEY_SIZE = 16,
|
||||
MAX_CMN_KEY = 0x05,
|
||||
MAX_NCCH_KEYX = MAX_U8
|
||||
} keydata_limits;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KEYSET_ERROR = -10,
|
||||
} keyset_errors;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RSA_1024_KEY_SIZE = 0x80,
|
||||
RSA_2048_KEY_SIZE = 0x100,
|
||||
RSA_4096_KEY_SIZE = 0x200,
|
||||
} rsa_keysize;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
pki_TEST,
|
||||
pki_BETA, // Not used, but is here for completeness
|
||||
pki_DEVELOPMENT,
|
||||
pki_PRODUCTION,
|
||||
pki_CUSTOM,
|
||||
} pki_keyset;
|
||||
|
||||
// Structs
|
||||
typedef struct
|
||||
{
|
||||
u8 *pub;
|
||||
u8 *pvt;
|
||||
} rsa2048_key;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pki_keyset keyset;
|
||||
bool keysetLoaded;
|
||||
bool dumpkeys;
|
||||
bool ignore_sign;
|
||||
|
||||
struct
|
||||
{
|
||||
u32 presetType;
|
||||
u32 targetFirmware;
|
||||
} accessDescSign;
|
||||
|
||||
struct
|
||||
{
|
||||
// CIA
|
||||
u8 **commonKey;
|
||||
u16 currentCommonKey;
|
||||
|
||||
// NCCH Keys
|
||||
u8 *normalKey;
|
||||
u8 *systemFixedKey;
|
||||
u8 **ncchKeyX;
|
||||
|
||||
u8 *ncchKey0;
|
||||
u8 *ncchKey1;
|
||||
|
||||
// CCI
|
||||
u8 *initialDataKeyX;
|
||||
} aes;
|
||||
|
||||
struct
|
||||
{
|
||||
// CIA RSA
|
||||
rsa2048_key cp;
|
||||
rsa2048_key xs;
|
||||
|
||||
// CCI/CFA
|
||||
rsa2048_key cciCfa;
|
||||
|
||||
// CXI
|
||||
rsa2048_key acex;
|
||||
rsa2048_key cxi;
|
||||
} rsa;
|
||||
|
||||
struct
|
||||
{
|
||||
// CIA
|
||||
u8 *caCert;
|
||||
u8 *xsCert;
|
||||
u8 *cpCert;
|
||||
} certs;
|
||||
} keys_struct;
|
||||
|
||||
// Public Prototypes
|
||||
void InitKeys(keys_struct *keys);
|
||||
int SetKeys(keys_struct *keys);
|
||||
void FreeKeys(keys_struct *keys);
|
||||
|
||||
int SetCommonKey(keys_struct *keys, const u8 *key, u8 Index);
|
||||
int SetCurrentCommonKey(keys_struct *keys, u8 Index);
|
||||
int SetNormalKey(keys_struct *keys, const u8 *key);
|
||||
int SetSystemFixedKey(keys_struct *keys, const u8 *key);
|
||||
int SetCciInitialDataKeyX(keys_struct *keys, const u8 *key);
|
||||
|
||||
void Rsa2048Key_Alloc(rsa2048_key* key);
|
||||
void Rsa2048Key_Free(rsa2048_key* key);
|
||||
void Rsa2048Key_Set(rsa2048_key* key, const u8* pvt, const u8* pub);
|
||||
bool Rsa2048Key_CanSign(const rsa2048_key* key);
|
||||
@@ -0,0 +1,39 @@
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <dirent.h>
|
||||
#include <wchar.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
#include "ctr_utils.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#include "keyset.h"
|
||||
#include "user_settings.h"
|
||||
#include "yaml_parser.h"
|
||||
#include "rsf_settings.h"
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
#include "lib.h"
|
||||
#include "ncch_build.h"
|
||||
#include "ncsd_build.h"
|
||||
#include "cia_build.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Setting up user settings
|
||||
user_settings *set = calloc(1,sizeof(user_settings));
|
||||
if(set == NULL) {
|
||||
fprintf(stderr,"[!] Not enough memory\n");
|
||||
return -1;
|
||||
}
|
||||
init_UserSettings(set);
|
||||
initRand();
|
||||
|
||||
int result;
|
||||
|
||||
// Parsing command args
|
||||
if((result = ParseArgs(argc,argv,set)) < 0)
|
||||
goto finish;
|
||||
|
||||
|
||||
// Import RSF Settings if present
|
||||
if((result = GetRsfSettings(set)) < 0)
|
||||
goto finish;
|
||||
|
||||
// Setup Content 0
|
||||
if(!set->ncch.buildNcch0){ // Import Content
|
||||
if(set->common.workingFileType == infile_ncch){
|
||||
if(!AssertFile(set->common.contentPath[0])){
|
||||
fprintf(stderr,"[MAKEROM ERROR] Failed to open Content 0: %s\n",set->common.contentPath[0]);
|
||||
goto finish;
|
||||
}
|
||||
u64 fileSize = GetFileSize64(set->common.contentPath[0]);
|
||||
u64 calcSize = 0;
|
||||
|
||||
FILE *ncch0 = fopen(set->common.contentPath[0],"rb");
|
||||
|
||||
ncch_hdr hdr;
|
||||
ReadNcchHdr(&hdr,ncch0);
|
||||
calcSize = GetNcchSize(&hdr);
|
||||
if(calcSize != fileSize){
|
||||
fprintf(stderr,"[MAKEROM ERROR] Content 0 is corrupt\n");
|
||||
fclose(ncch0);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
set->common.workingFile.size = fileSize;
|
||||
set->common.workingFile.buffer = malloc(fileSize);
|
||||
ReadFile64(set->common.workingFile.buffer, set->common.workingFile.size,0,ncch0);
|
||||
fclose(ncch0);
|
||||
}
|
||||
else{
|
||||
if(!AssertFile(set->common.workingFilePath)) {
|
||||
fprintf(stderr,"[MAKEROM ERROR] Failed to open: %s\n",set->common.workingFilePath);
|
||||
goto finish;
|
||||
}
|
||||
u64 size = GetFileSize64(set->common.workingFilePath);
|
||||
set->common.workingFile.size = align(size,0x10);
|
||||
set->common.workingFile.buffer = malloc(set->common.workingFile.size);
|
||||
FILE *fp = fopen(set->common.workingFilePath,"rb");
|
||||
ReadFile64(set->common.workingFile.buffer,size,0,fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
else{// Build Content 0
|
||||
result = build_NCCH(set);
|
||||
if(result < 0) {
|
||||
//fprintf(stderr,"[ERROR] %s generation failed\n",set->build_ncch_type == CXI? "CXI" : "CFA");
|
||||
fprintf(stderr,"[RESULT] Failed to build NCCH (ret = %d)\n", result);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
// Make CCI
|
||||
if(set->common.outFormat == CCI){
|
||||
result = build_CCI(set);
|
||||
if(result < 0) {
|
||||
fprintf(stderr,"[RESULT] Failed to build CCI (ret = %d)\n", result);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
// Make CIA
|
||||
else if(set->common.outFormat == CIA){
|
||||
result = build_CIA(set);
|
||||
if(result < 0) {
|
||||
fprintf(stderr,"[RESULT] Failed to build CIA (ret = %d)\n", result);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
// No Container Raw CXI/CFA
|
||||
else if(set->common.outFormat == CXI || set->common.outFormat == CFA){
|
||||
FILE *ncch_out = fopen(set->common.outFileName,"wb");
|
||||
if(!ncch_out) {
|
||||
fprintf(stderr,"[MAKEROM ERROR] Failed to create '%s'\n",set->common.outFileName);
|
||||
fprintf(stderr,"[RESULT] Failed to build '%s'\n",set->common.outFormat == CXI? "CXI" : "CFA");
|
||||
result = FAILED_TO_CREATE_OUTFILE;
|
||||
goto finish;
|
||||
}
|
||||
WriteBuffer(set->common.workingFile.buffer,set->common.workingFile.size,0,ncch_out);
|
||||
fclose(ncch_out);
|
||||
}
|
||||
|
||||
finish:
|
||||
free_UserSettings(set);
|
||||
return result;
|
||||
}
|
||||
+1201
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,156 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NCCH_MEMERROR = -1,
|
||||
SAVE_DATA_TOO_LARGE = -2,
|
||||
NCCH_SECTION_NOT_EXIST = -3,
|
||||
UNABLE_TO_LOAD_NCCH_KEY = -4,
|
||||
NCCH_EXPORT_BUFFER_TOO_SMALL = -5,
|
||||
NO_ROMFS_IN_CFA = -6,
|
||||
NO_EXHEADER_IN_CXI = -7,
|
||||
NO_EXEFS_IN_CXI = -8,
|
||||
// SigCheck Errors
|
||||
CXI_CORRUPT = -9,
|
||||
ACCESSDESC_SIG_BAD = -10,
|
||||
NCCH_HDR_SIG_BAD = -11,
|
||||
// HashCheck Errors
|
||||
EXHDR_CORRUPT = -12,
|
||||
LOGO_CORRUPT = -13,
|
||||
EXEFS_CORRUPT = -14,
|
||||
ROMFS_CORRUPT = -15,
|
||||
// Others
|
||||
NCCH_BAD_RSF_SET = -16,
|
||||
DATA_POS_DNE = -17,
|
||||
} ncch_errors;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ncch_exhdr = 1,
|
||||
ncch_exefs,
|
||||
ncch_romfs,
|
||||
} ncch_section;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ncchflag_CONTENT_KEYX = 3,
|
||||
ncchflag_CONTENT_PLATFORM = 4,
|
||||
ncchflag_CONTENT_TYPE = 5,
|
||||
ncchflag_CONTENT_BLOCK_SIZE = 6,
|
||||
ncchflag_OTHER_FLAG = 7
|
||||
} ncch_flags;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
otherflag_Clear = 0,
|
||||
otherflag_FixedCryptoKey = (1 << 0),
|
||||
otherflag_NoMountRomFs = (1 << 1),
|
||||
otherflag_NoCrypto = (1 << 2),
|
||||
} ncch_otherflag_bitmask;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
form_Unassigned,
|
||||
form_SimpleContent,
|
||||
form_ExecutableWithoutRomfs,
|
||||
form_Executable
|
||||
} ncch_form_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
content_Application,
|
||||
content_SystemUpdate,
|
||||
content_Manual,
|
||||
content_Child,
|
||||
content_Trial,
|
||||
content_ExtendedSystemUpdate
|
||||
} ncch_content_bitmask;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
platform_CTR = 0x1,
|
||||
platform_SNAKE = 0x2
|
||||
} ncch_platform;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
keyx_regular = 0x00,
|
||||
keyx_7_0 = 0x01,
|
||||
keyx_9_3 = 0x0A,
|
||||
keyx_9_6 = 0x0B,
|
||||
} ncch_keyx_id;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u16 formatVersion;
|
||||
u32 exhdrOffset;
|
||||
u32 exhdrSize;
|
||||
u32 acexOffset;
|
||||
u32 acexSize;
|
||||
u64 logoOffset;
|
||||
u64 logoSize;
|
||||
u64 plainRegionOffset;
|
||||
u64 plainRegionSize;
|
||||
u64 exefsOffset;
|
||||
u64 exefsSize;
|
||||
u64 exefsHashDataSize;
|
||||
u64 romfsOffset;
|
||||
u64 romfsSize;
|
||||
u64 romfsHashDataSize;
|
||||
u64 titleId;
|
||||
u64 programId;
|
||||
} ncch_info;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 signature[0x100];
|
||||
u8 magic[4];
|
||||
u8 ncchSize[4];
|
||||
u8 titleId[8];
|
||||
u8 makerCode[2];
|
||||
u8 formatVersion[2];
|
||||
u8 padding0[4];
|
||||
u8 programId[8];
|
||||
u8 padding1[0x10];
|
||||
u8 logoHash[0x20]; // SHA-256 over the entire logo region
|
||||
u8 productCode[0x10];
|
||||
u8 exhdrHash[0x20]; // SHA-256 over exhdrSize of the exhdr region
|
||||
u8 exhdrSize[4];
|
||||
u8 padding2[4];
|
||||
u8 flags[8];
|
||||
u8 plainRegionOffset[4];
|
||||
u8 plainRegionSize[4];
|
||||
u8 logoOffset[4];
|
||||
u8 logoSize[4];
|
||||
u8 exefsOffset[4];
|
||||
u8 exefsSize[4];
|
||||
u8 exefsHashSize[4];
|
||||
u8 padding4[4];
|
||||
u8 romfsOffset[4];
|
||||
u8 romfsSize[4];
|
||||
u8 romfsHashSize[4];
|
||||
u8 padding5[4];
|
||||
u8 exefsHash[0x20];
|
||||
u8 romfsHash[0x20];
|
||||
} ncch_hdr;
|
||||
|
||||
// NCCH Read Functions
|
||||
int VerifyNcch(u8 *ncch, keys_struct *keys, bool checkHash, bool suppressOutput);
|
||||
|
||||
int ModifyNcchIds(u8 *ncch, u8 *titleId, u8 *programId, keys_struct *keys);
|
||||
|
||||
void ReadNcchHdr(ncch_hdr *hdr, FILE *fp);
|
||||
u8* GetNcchHdrSig(ncch_hdr *hdr);
|
||||
u8* GetNcchHdrData(ncch_hdr *hdr);
|
||||
u32 GetNcchHdrSigLen(ncch_hdr *hdr);
|
||||
u32 GetNcchHdrDataLen(ncch_hdr *hdr);
|
||||
bool IsNcch(FILE *fp, u8 *buf);
|
||||
bool IsCfa(ncch_hdr* hdr);
|
||||
bool IsUpdateCfa(ncch_hdr* hdr);
|
||||
u32 GetNcchBlockSize(ncch_hdr* hdr);
|
||||
u64 GetNcchSize(ncch_hdr* hdr);
|
||||
bool IsNcchEncrypted(ncch_hdr *hdr);
|
||||
bool SetNcchKeys(keys_struct *keys, ncch_hdr *hdr);
|
||||
int GetNcchInfo(ncch_info *ctx, ncch_hdr *header);
|
||||
void GetNcchAesCounter(u8 ctr[16], u64 titleId, u8 type);
|
||||
void CryptNcchRegion(u8 *buffer, u64 size, u64 src_pos, u64 titleId, u8 key[16], u8 type);
|
||||
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
#include "ncch.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
buffer_struct *out;
|
||||
keys_struct *keys;
|
||||
rsf_settings *rsfSet;
|
||||
|
||||
struct
|
||||
{
|
||||
u32 blockSize;
|
||||
bool verbose;
|
||||
bool IncludeExeFsLogo;
|
||||
bool CompressCode;
|
||||
bool UseOnSD;
|
||||
bool Encrypt;
|
||||
bool FreeProductCode;
|
||||
bool IsCfa;
|
||||
bool IsBuildingCodeSection;
|
||||
bool UseRomFS;
|
||||
bool noCodePadding;
|
||||
|
||||
bool useSecCrypto;
|
||||
u8 keyXID;
|
||||
} options;
|
||||
|
||||
struct
|
||||
{
|
||||
FILE *elf;
|
||||
u64 elfSize;
|
||||
|
||||
FILE *banner;
|
||||
u64 bannerSize;
|
||||
|
||||
FILE *icon;
|
||||
u64 iconSize;
|
||||
|
||||
FILE *logo;
|
||||
u64 logoSize;
|
||||
|
||||
FILE *code;
|
||||
u64 codeSize;
|
||||
|
||||
FILE *exhdr;
|
||||
u64 exhdrSize;
|
||||
|
||||
FILE *romfs;
|
||||
u64 romfsSize;
|
||||
|
||||
FILE *plainregion;
|
||||
u64 plainregionSize;
|
||||
} componentFilePtrs;
|
||||
|
||||
struct
|
||||
{
|
||||
buffer_struct code;
|
||||
buffer_struct banner;
|
||||
buffer_struct icon;
|
||||
} exefsSections;
|
||||
|
||||
struct
|
||||
{
|
||||
u32 textAddress;
|
||||
u32 textSize;
|
||||
u32 textMaxPages;
|
||||
u32 roAddress;
|
||||
u32 roSize;
|
||||
u32 roMaxPages;
|
||||
u32 rwAddress;
|
||||
u32 rwSize;
|
||||
u32 rwMaxPages;
|
||||
u32 bssSize;
|
||||
u32 stackSize;
|
||||
} codeDetails;
|
||||
|
||||
struct
|
||||
{
|
||||
buffer_struct exhdr;
|
||||
buffer_struct acexDesc;
|
||||
buffer_struct logo;
|
||||
buffer_struct plainRegion;
|
||||
buffer_struct exeFs;
|
||||
} sections;
|
||||
|
||||
ncch_info cryptoDetails;
|
||||
} ncch_settings;
|
||||
|
||||
// NCCH Build Functions
|
||||
int build_NCCH(user_settings *usrset);
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
#include "ncch.h"
|
||||
@@ -0,0 +1,727 @@
|
||||
#include "lib.h"
|
||||
|
||||
#include "ncch_read.h"
|
||||
#include "exheader_read.h"
|
||||
#include "tik_read.h"
|
||||
#include "tmd_read.h"
|
||||
#include "cia_read.h"
|
||||
|
||||
#include "ncsd_build.h"
|
||||
#include "cardinfo.h"
|
||||
#include "titleid.h"
|
||||
|
||||
const int NCCH0_OFFSET = 0x4000;
|
||||
const int CCI_BLOCK_SIZE = 0x200;
|
||||
|
||||
const char MEDIA_SIZE_STR[10][6] = {"128MB","256MB","512MB","1GB","2GB","4GB","8GB","16GB","32GB"};
|
||||
|
||||
void ImportCciSettings(cci_settings *set, user_settings *usrset);
|
||||
void FreeCciSettings(cci_settings *set);
|
||||
int ImportCciNcch(cci_settings *set);
|
||||
int ProcessNcchForCci(cci_settings *set);
|
||||
int GenCciHdr(cci_settings *set);
|
||||
int CheckRomConfig(cci_settings *set);
|
||||
void WriteCciDataToOutput(cci_settings *set);
|
||||
|
||||
int build_CCI(user_settings *usrset)
|
||||
{
|
||||
int result = 0;
|
||||
cci_settings *set = calloc(1,sizeof(cci_settings));
|
||||
if(!set){
|
||||
fprintf(stderr,"[CCI ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
ImportCciSettings(set,usrset);
|
||||
|
||||
if(ImportCciNcch(set)){
|
||||
result = FAILED_TO_IMPORT_FILE;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if(ProcessNcchForCci(set)){
|
||||
result = FAILED_TO_IMPORT_FILE;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if(GenCciHdr(set)){
|
||||
result = GEN_HDR_FAIL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if(GenCardInfoHdr(set)){
|
||||
result = GEN_HDR_FAIL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if(CheckRomConfig(set)){
|
||||
result = CCI_CONFIG_FAIL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
set->out = fopen(usrset->common.outFileName,"wb");
|
||||
if(!set->out){
|
||||
fprintf(stderr,"[CCI ERROR] Failed to create '%s'\n",usrset->common.outFileName);
|
||||
result = FAILED_TO_CREATE_OUTFILE;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
WriteCciDataToOutput(set);
|
||||
|
||||
finish:
|
||||
FreeCciSettings(set);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ImportCciSettings(cci_settings *set, user_settings *usrset)
|
||||
{
|
||||
set->keys = &usrset->common.keys;
|
||||
set->rsf = &usrset->common.rsfSet;
|
||||
|
||||
set->content.data = usrset->common.workingFile.buffer;
|
||||
set->content.dataLen = usrset->common.workingFile.size;
|
||||
set->content.dataType = usrset->common.workingFileType;
|
||||
|
||||
set->content.path = usrset->common.contentPath;
|
||||
set->content.dSize = usrset->common.contentSize;
|
||||
|
||||
usrset->common.workingFile.buffer = NULL;
|
||||
usrset->common.workingFile.size = 0;
|
||||
|
||||
set->options.verbose = usrset->common.verbose;
|
||||
set->options.padCci = set->rsf->Option.MediaFootPadding;
|
||||
set->options.noModTid = usrset->cci.dontModifyNcchTitleID;
|
||||
set->options.useExternalSdkCardInfo = usrset->cci.useSDKStockData;
|
||||
set->options.closeAlignWR = usrset->cci.closeAlignWritableRegion;
|
||||
|
||||
set->options.cverDataType = usrset->cci.cverDataType;
|
||||
set->options.cverDataPath = usrset->cci.cverDataPath;
|
||||
|
||||
set->romInfo.blockSize = CCI_BLOCK_SIZE;
|
||||
set->romInfo.saveSize = 0;
|
||||
}
|
||||
|
||||
void FreeCciSettings(cci_settings *set)
|
||||
{
|
||||
free(set->options.tmdHdr);
|
||||
free(set->content.data);
|
||||
free(set->headers.ccihdr.buffer);
|
||||
free(set->headers.cardinfohdr.buffer);
|
||||
if(set->out)
|
||||
fclose(set->out);
|
||||
free(set);
|
||||
}
|
||||
|
||||
int ImportNcchForCci(cci_settings *set)
|
||||
{
|
||||
for(int i = 0; i < CCI_MAX_CONTENT; i++){
|
||||
if(i == 0){
|
||||
set->content.active[i] = true;
|
||||
set->content.dSize[i] = set->content.dataLen;
|
||||
set->content.dOffset[i] = 0;
|
||||
}
|
||||
else if(set->content.dSize[i] && set->content.path[i]){
|
||||
set->content.active[i] = true;
|
||||
set->content.dOffset[i] = set->content.dataLen;
|
||||
set->content.dataLen += set->content.dSize[i];
|
||||
}
|
||||
else
|
||||
set->content.active[i] = false;
|
||||
}
|
||||
|
||||
set->content.data = realloc(set->content.data,set->content.dataLen);
|
||||
if(!set->content.data){
|
||||
fprintf(stderr,"[CCI ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
|
||||
FILE *ncch;
|
||||
for(int i = 1; i < CCI_MAX_CONTENT; i++){
|
||||
if(!set->content.active[i])
|
||||
continue;
|
||||
|
||||
u8 *ncchpos = (u8*)(set->content.data+set->content.dOffset[i]);
|
||||
|
||||
ncch = fopen(set->content.path[i],"rb");
|
||||
|
||||
ReadFile64(ncchpos, set->content.dSize[i], 0, ncch);
|
||||
|
||||
fclose(ncch);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CanCiaBeCci(u64 titleId, u16 count, tmd_content_chunk *content)
|
||||
{
|
||||
if(GetTidCategory(titleId) != PROGRAM_ID_CATEGORY_APPLICATION)
|
||||
return false;
|
||||
|
||||
if(count > CCI_MAX_CONTENT)
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < count; i++){
|
||||
if(GetTmdContentIndex(content[i]) >= CCI_MAX_CONTENT)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ProcessCiaForCci(cci_settings *set)
|
||||
{
|
||||
if(!IsCia(set->content.data)){
|
||||
fprintf(stderr,"[CCI ERROR] CIA is corrupt\n");
|
||||
return FAILED_TO_IMPORT_FILE;
|
||||
}
|
||||
|
||||
tik_hdr *tik = GetTikHdr(GetCiaTik(set->content.data));
|
||||
tmd_hdr *tmd = GetTmdHdr(GetCiaTmd(set->content.data));
|
||||
tmd_content_chunk *contentInfo = GetTmdContentInfo(GetCiaTmd(set->content.data));
|
||||
u64 contentOffset = GetCiaContentOffset((cia_hdr*)set->content.data);
|
||||
|
||||
u16 contentCount = GetTmdContentCount(tmd);
|
||||
set->romInfo.saveSize = GetTmdSaveSize(tmd);
|
||||
|
||||
if(!CanCiaBeCci(GetTmdTitleId(tmd),contentCount,contentInfo)){
|
||||
fprintf(stderr,"[CCI ERROR] This CIA cannot be converted to CCI\n");
|
||||
return INCOMPAT_CIA;
|
||||
}
|
||||
|
||||
bool canDecrypt;
|
||||
u8 titleKey[AES_128_KEY_SIZE];
|
||||
canDecrypt = GetTikTitleKey(titleKey,tik,set->keys);
|
||||
if(set->options.verbose){
|
||||
if(canDecrypt)
|
||||
memdump(stdout,"[CCI] CIA title key: ",titleKey,AES_128_KEY_SIZE);
|
||||
else
|
||||
fprintf(stdout,"[CCI] CIA title key could not be decrypted\n");
|
||||
}
|
||||
|
||||
for(u16 i = 0; i < contentCount; i++){
|
||||
u16 index = GetTmdContentIndex(contentInfo[i]);
|
||||
set->content.active[index] = true;
|
||||
set->content.dOffset[index] = contentOffset;
|
||||
set->content.dSize[index] = GetTmdContentSize(contentInfo[i]);
|
||||
u8 *content = set->content.data + contentOffset;
|
||||
if(IsTmdContentEncrypted(contentInfo[i])){
|
||||
if(canDecrypt)
|
||||
CryptContent(content,content,set->content.dSize[index],titleKey,i,DEC);
|
||||
else{
|
||||
fprintf(stderr,"[CCI ERROR] Failed to decrypt CIA content: 0x%08x\n",GetTmdContentId(contentInfo[i]));
|
||||
return INCOMPAT_CIA;
|
||||
}
|
||||
}
|
||||
if(!ValidateTmdContent(content,contentInfo[i])){
|
||||
fprintf(stderr,"[CCI ERROR] CIA content: 0x%08x is corrupt\n",GetTmdContentId(contentInfo[i]));
|
||||
return NCSD_INVALID_NCCH;
|
||||
}
|
||||
|
||||
contentOffset += set->content.dSize[index];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This need to be more automagical */
|
||||
void GetTitleSaveSize(cci_settings *set)
|
||||
{
|
||||
if(set->rsf->SystemControlInfo.SaveDataSize)
|
||||
GetSaveDataSizeFromString(&set->romInfo.saveSize,set->rsf->SystemControlInfo.SaveDataSize,"CCI");
|
||||
|
||||
// Adjusting save size
|
||||
if(set->romInfo.saveSize > 0 && set->romInfo.saveSize < (u64)(128*KB))
|
||||
set->romInfo.saveSize = (u64)(128*KB);
|
||||
else if(set->romInfo.saveSize > (u64)(128*KB) && set->romInfo.saveSize < (u64)(512*KB))
|
||||
set->romInfo.saveSize = (u64)(512*KB);
|
||||
else if(set->romInfo.saveSize > (u64)(512*KB))
|
||||
set->romInfo.saveSize = align(set->romInfo.saveSize,MB);
|
||||
}
|
||||
|
||||
int ImportCciNcch(cci_settings *set)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if(set->content.dataType == infile_ncch)
|
||||
ret = ImportNcchForCci(set);
|
||||
else if(set->content.dataType == infile_cia)
|
||||
ret = ProcessCiaForCci(set);
|
||||
else{
|
||||
fprintf(stderr,"[CCI ERROR] Unrecognised input data type\n");
|
||||
return FAILED_TO_IMPORT_FILE;
|
||||
}
|
||||
|
||||
GetTitleSaveSize(set);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ProcessCverDataForCci(cci_settings *set)
|
||||
{
|
||||
u64 tmdSize,tmdOffset;
|
||||
|
||||
u64 dataSize = GetFileSize64(set->options.cverDataPath);
|
||||
FILE *data = fopen(set->options.cverDataPath,"rb");
|
||||
|
||||
|
||||
if(set->options.cverDataType == CVER_DTYPE_CIA){
|
||||
cia_hdr *ciaHdr = calloc(1,sizeof(cia_hdr));
|
||||
ReadFile64(ciaHdr,sizeof(cia_hdr),0,data);
|
||||
|
||||
tmdSize = GetCiaTmdSize(ciaHdr);
|
||||
tmdOffset = GetCiaTmdOffset(ciaHdr);
|
||||
|
||||
free(ciaHdr);
|
||||
}
|
||||
else{
|
||||
tmdSize = dataSize;
|
||||
tmdOffset = 0;
|
||||
}
|
||||
|
||||
u8 *tmd = calloc(1,tmdSize);
|
||||
|
||||
ReadFile64(tmd,tmdSize,tmdOffset,data);
|
||||
fclose(data);
|
||||
|
||||
tmd_hdr *tmdHdr = GetTmdHdr(tmd);
|
||||
if(!tmdHdr){
|
||||
fprintf(stderr,"[CCI ERROR] Corrupt cver TMD\n");
|
||||
free(tmd);
|
||||
return FAILED_TO_IMPORT_FILE;
|
||||
}
|
||||
|
||||
set->options.tmdHdr = calloc(1,sizeof(tmd_hdr));
|
||||
memcpy(set->options.tmdHdr,tmdHdr,sizeof(tmd_hdr));
|
||||
|
||||
free(tmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GetNewNcchIdForCci(u8 *newTid, u8 *srcTid, u8 index, tmd_hdr *tmdHdr)
|
||||
{
|
||||
u64 titleId = u8_to_u64(srcTid,LE) & 0xffffffffffff;
|
||||
if(tmdHdr && index == 7)
|
||||
titleId |= (u64)(GetTmdVersion(tmdHdr)) << 48;
|
||||
else
|
||||
titleId |= (u64)(index+4) << 48;
|
||||
|
||||
u64_to_u8(newTid,titleId,LE);
|
||||
}
|
||||
|
||||
int ProcessNcchForCci(cci_settings *set)
|
||||
{
|
||||
u8 *ncch;
|
||||
ncch_hdr *hdr;
|
||||
|
||||
u8 titleId[8];
|
||||
u8 srcId[8];
|
||||
|
||||
if(set->options.cverDataPath && set->content.active[7]){
|
||||
if(ProcessCverDataForCci(set))
|
||||
return FAILED_TO_IMPORT_FILE;
|
||||
}
|
||||
|
||||
for(int i = 0; i < CCI_MAX_CONTENT; i++){
|
||||
if(set->content.active[i]){
|
||||
ncch = set->content.data + set->content.dOffset[i];
|
||||
if(!IsNcch(NULL,ncch)){
|
||||
fprintf(stderr,"[CCI ERROR] NCCH %d is corrupt\n",i);
|
||||
return NCSD_INVALID_NCCH;
|
||||
}
|
||||
hdr = (ncch_hdr*)ncch;
|
||||
if(i > 0 && !set->options.noModTid){
|
||||
if(set->options.verbose){
|
||||
printf("[CCI] Modifying NCCH %d IDs\n",i);
|
||||
printf("[Old Ids]\n");
|
||||
memdump(stdout," > TitleId: 0x",hdr->titleId,8);
|
||||
memdump(stdout," > ProgramId: 0x",hdr->programId,8);
|
||||
}
|
||||
GetNewNcchIdForCci(titleId,srcId,i,set->options.tmdHdr);
|
||||
if(ModifyNcchIds(ncch, titleId, srcId, set->keys))
|
||||
return -1;
|
||||
if(set->options.verbose){
|
||||
printf("[New Ids]\n");
|
||||
memdump(stdout," > TitleId: 0x",hdr->titleId,8);
|
||||
memdump(stdout," > ProgramId: 0x",hdr->programId,8);
|
||||
}
|
||||
}
|
||||
set->content.titleId[i] = u8_to_u64(hdr->titleId,LE);
|
||||
if(i == 0)
|
||||
memcpy(srcId,hdr->titleId,8);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetCciNcchInfo(cci_hdr *hdr, cci_settings *set)
|
||||
{
|
||||
u64 ncchSize,ncchOffset;
|
||||
|
||||
ncchOffset = NCCH0_OFFSET;
|
||||
|
||||
for(int i = 0; i < CCI_MAX_CONTENT; i++){
|
||||
if(set->content.active[i]){
|
||||
set->content.cOffset[i] = ncchOffset;
|
||||
ncchSize = align(set->content.dSize[i],set->romInfo.blockSize);
|
||||
|
||||
u32_to_u8(hdr->offset_sizeTable[i].offset,(ncchOffset/set->romInfo.blockSize),LE);
|
||||
u32_to_u8(hdr->offset_sizeTable[i].size,(ncchSize/set->romInfo.blockSize),LE);
|
||||
u64_to_u8(hdr->ncchIdTable[i],set->content.titleId[i],LE);
|
||||
|
||||
ncchOffset += ncchSize;
|
||||
}
|
||||
}
|
||||
|
||||
set->romInfo.usedSize = ncchOffset;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int SetMediaSize(u8 *mediaSize, cci_settings *set)
|
||||
{
|
||||
char *str = set->rsf->CardInfo.MediaSize;
|
||||
if(str){
|
||||
if(strcasecmp(str,"128MB") == 0) set->romInfo.mediaSize = (u64)MB*128;
|
||||
else if(strcasecmp(str,"256MB") == 0) set->romInfo.mediaSize = (u64)MB*256;
|
||||
else if(strcasecmp(str,"512MB") == 0) set->romInfo.mediaSize = (u64)MB*512;
|
||||
else if(strcasecmp(str,"1GB") == 0) set->romInfo.mediaSize = (u64)GB*1;
|
||||
else if(strcasecmp(str,"2GB") == 0) set->romInfo.mediaSize = (u64)GB*2;
|
||||
else if(strcasecmp(str,"4GB") == 0) set->romInfo.mediaSize = (u64)GB*4;
|
||||
else if(strcasecmp(str,"8GB") == 0) set->romInfo.mediaSize = (u64)GB*8;
|
||||
//else if(strcasecmp(str,"16GB") == 0) set->romInfo.mediaSize = (u64)GB*16;
|
||||
//else if(strcasecmp(str,"32GB") == 0) set->romInfo.mediaSize = (u64)GB*32;
|
||||
else {
|
||||
fprintf(stderr,"[CCI ERROR] Invalid MediaSize: %s\n",str);
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
}
|
||||
else{
|
||||
u64 dataSize = set->romInfo.usedSize + (set->romInfo.saveSize >= MB ? set->romInfo.saveSize : 0);
|
||||
if(dataSize < (u64)MB*128)
|
||||
set->romInfo.mediaSize = (u64)MB*128;
|
||||
else if(dataSize < (u64)MB*256)
|
||||
set->romInfo.mediaSize = (u64)MB*256;
|
||||
else if(dataSize < (u64)MB*512)
|
||||
set->romInfo.mediaSize = (u64)MB*512;
|
||||
else if(dataSize < (u64)GB*1)
|
||||
set->romInfo.mediaSize = (u64)GB*1;
|
||||
else if(dataSize < (u64)GB*2)
|
||||
set->romInfo.mediaSize = (u64)GB*2;
|
||||
else if(dataSize < (u64)GB*4)
|
||||
set->romInfo.mediaSize = (u64)GB*4;
|
||||
else if(dataSize < (u64)GB*8)
|
||||
set->romInfo.mediaSize = (u64)GB*8;
|
||||
//else if(dataSize < (u64)GB*16)
|
||||
// set->romInfo.mediaSize = (u64)GB*16;
|
||||
//else if(dataSize < (u64)GB*32)
|
||||
// set->romInfo.mediaSize = (u64)GB*32;
|
||||
else {
|
||||
fprintf(stderr,"[CCI ERROR] NCCH Partitions are too large\n");
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
}
|
||||
|
||||
u32_to_u8(mediaSize,(set->romInfo.mediaSize/set->romInfo.blockSize),LE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetBackupWriteWaitTime(u8 *flag, rsf_settings *rsf)
|
||||
{
|
||||
char *str = rsf->CardInfo.BackupWriteWaitTime;
|
||||
if(!str)
|
||||
*flag = 0;
|
||||
else{
|
||||
u32 waitTime = strtoul(str,NULL,0);
|
||||
if(waitTime > 255){
|
||||
fprintf(stderr,"[CCI ERROR] Invalid Card BackupWriteWaitTime (%d) : must 0-255\n",waitTime);
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
*flag = (u8)waitTime;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetMediaType(u8 *flag, cci_settings *set)
|
||||
{
|
||||
char *str = set->rsf->CardInfo.MediaType;
|
||||
|
||||
if(str){
|
||||
if(strcasecmp(str,"Card1") == 0)
|
||||
*flag = mediatype_CARD1;
|
||||
else if(strcasecmp(str,"Card2") == 0)
|
||||
*flag = mediatype_CARD2;
|
||||
else {
|
||||
fprintf(stderr,"[CCI ERROR] Invalid MediaType: %s\n",str);
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(set->romInfo.saveSize >= (u64)1*MB)
|
||||
*flag = mediatype_CARD2;
|
||||
else
|
||||
*flag = mediatype_CARD1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetCardDevice(u8 *flags, u64 saveSize, rsf_settings *rsf)
|
||||
{
|
||||
u8 saveCrypto;
|
||||
|
||||
if(!rsf->CardInfo.SaveCrypto)
|
||||
saveCrypto = 3;
|
||||
else{
|
||||
if(strcasecmp(rsf->CardInfo.SaveCrypto,"fw1") == 0 || strcasecmp(rsf->CardInfo.SaveCrypto,"ctr fail") == 0 ) saveCrypto = 1;
|
||||
else if(strcasecmp(rsf->CardInfo.SaveCrypto,"fw2") == 0) saveCrypto = 2;
|
||||
else if(strcasecmp(rsf->CardInfo.SaveCrypto,"fw3") == 0) saveCrypto = 3;
|
||||
else if(strcasecmp(rsf->CardInfo.SaveCrypto,"fw6") == 0) saveCrypto = 6;
|
||||
else {
|
||||
fprintf(stderr,"[CCI ERROR] Invalid SaveCrypto: %s\n",rsf->CardInfo.SaveCrypto);
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* FW6x SaveCrypto */
|
||||
if(saveCrypto == 6)
|
||||
flags[cciflag_FW6_SAVE_CRYPTO] = 1;
|
||||
else
|
||||
flags[cciflag_FW6_SAVE_CRYPTO] = 0;
|
||||
|
||||
/* CardDevice */
|
||||
u8 cardDevice = 0;
|
||||
if(rsf->CardInfo.CardDevice){
|
||||
if(strcmp(rsf->CardInfo.CardDevice,"NorFlash") == 0)
|
||||
cardDevice = carddevice_NOR_FLASH;
|
||||
else if(strcmp(rsf->CardInfo.CardDevice,"None") == 0)
|
||||
cardDevice = carddevice_NONE;
|
||||
else if(strcmp(rsf->CardInfo.CardDevice,"BT") == 0)
|
||||
cardDevice = carddevice_BT;
|
||||
else {
|
||||
fprintf(stderr,"[CCI ERROR] Invalid CardDevice: %s\n",rsf->CardInfo.CardDevice);
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(saveSize == 0 || saveSize >= (u64)1*MB)
|
||||
cardDevice = carddevice_NONE;
|
||||
else
|
||||
cardDevice = carddevice_NOR_FLASH;
|
||||
}
|
||||
|
||||
if(flags[cciflag_MEDIA_TYPE] == mediatype_CARD1){
|
||||
if(saveSize != (u64)(128*KB) && saveSize != (u64)(512*KB) && cardDevice == carddevice_NOR_FLASH){
|
||||
fprintf(stderr,"[CCI ERROR] 'CardDevice: NorFlash' can only be used with save-data sizes: 128K & 512K\n");
|
||||
return INVALID_RSF_OPT;
|
||||
}
|
||||
}
|
||||
if(flags[cciflag_MEDIA_TYPE] == mediatype_CARD2){
|
||||
if(cardDevice == carddevice_NOR_FLASH){
|
||||
fprintf(stderr,"[CCI WARNING] 'CardDevice: NorFlash' is invalid for Card2\n");
|
||||
cardDevice = carddevice_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if(saveCrypto > 1)
|
||||
flags[saveCrypto == 2? cciflag_CARD_DEVICE_OLD : cciflag_CARD_DEVICE] = cardDevice;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetCciFlags(u8 *flags, cci_settings *set)
|
||||
{
|
||||
// Backup Write Wait Time
|
||||
if(SetBackupWriteWaitTime(&flags[cciflag_BACKUP_WRITE_WAIT_TIME], set->rsf))
|
||||
return INVALID_RSF_OPT;
|
||||
// Platform
|
||||
flags[cciflag_MEDIA_PLATFORM] = cciplatform_CTR;
|
||||
// Card Type
|
||||
if(SetMediaType(&flags[cciflag_MEDIA_TYPE], set))
|
||||
return INVALID_RSF_OPT;
|
||||
// Media Unit
|
||||
flags[cciflag_MEDIA_BLOCK_SIZE] = GetCtrBlockSizeFlag(set->romInfo.blockSize);
|
||||
// Card Device
|
||||
if(SetCardDevice(flags, set->romInfo.saveSize, set->rsf))
|
||||
return INVALID_RSF_OPT;
|
||||
|
||||
set->romInfo.mediaType = flags[cciflag_MEDIA_TYPE];
|
||||
set->romInfo.cardDevice = flags[cciflag_CARD_DEVICE] | flags[cciflag_CARD_DEVICE_OLD];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GenCciHdr(cci_settings *set)
|
||||
{
|
||||
set->headers.ccihdr.size = sizeof(cci_hdr);
|
||||
set->headers.ccihdr.buffer = calloc(1,set->headers.ccihdr.size);
|
||||
if(!set->headers.ccihdr.buffer){
|
||||
set->headers.ccihdr.size = 0;
|
||||
fprintf(stderr,"[CCI ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
|
||||
cci_hdr *hdr = (cci_hdr*)set->headers.ccihdr.buffer;
|
||||
|
||||
// Magic & TitleId
|
||||
memcpy(hdr->magic,"NCSD",4);
|
||||
u64_to_u8(hdr->titleId,set->content.titleId[0],LE);
|
||||
|
||||
|
||||
SetCciNcchInfo(hdr,set);
|
||||
if(SetMediaSize(hdr->mediaSize,set))
|
||||
return GEN_HDR_FAIL;
|
||||
if(SetCciFlags(hdr->flags,set))
|
||||
return GEN_HDR_FAIL;
|
||||
|
||||
|
||||
// Sign Header
|
||||
if (Rsa2048Key_CanSign(&set->keys->rsa.cciCfa) == false)
|
||||
{
|
||||
printf("[NCSD WARNING] Failed to sign header\n");
|
||||
memset(hdr->signature, 0xFF, 0x100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rsa_ret = RsaSignVerify(&hdr->magic, sizeof(cci_hdr) - RSA_2048_KEY_SIZE, hdr->signature, set->keys->rsa.cciCfa.pub, set->keys->rsa.cciCfa.pvt, RSA_2048_SHA256, CTR_RSA_SIGN);
|
||||
if (rsa_ret != 0)
|
||||
{
|
||||
printf("[NCSD WARNING] Failed to sign header (mbedtls error = -0x%x)\n", -rsa_ret);
|
||||
memset(hdr->signature, 0xFF, 0x100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* GetMediaSizeStr(u64 mediaSize)
|
||||
{
|
||||
//MEDIA_SIZE_STR
|
||||
switch(mediaSize){
|
||||
case (u64)MB*128: return (char*)MEDIA_SIZE_STR[0];
|
||||
case (u64)MB*256: return (char*)MEDIA_SIZE_STR[1];
|
||||
case (u64)MB*512: return (char*)MEDIA_SIZE_STR[2];
|
||||
case (u64)GB*1: return (char*)MEDIA_SIZE_STR[3];
|
||||
case (u64)GB*2: return (char*)MEDIA_SIZE_STR[4];
|
||||
case (u64)GB*4: return (char*)MEDIA_SIZE_STR[5];
|
||||
case (u64)GB*8: return (char*)MEDIA_SIZE_STR[6];
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int CheckRomConfig(cci_settings *set)
|
||||
{
|
||||
u64 cciUsedSize;
|
||||
if(set->romInfo.mediaType == mediatype_CARD2)
|
||||
cciUsedSize = set->romInfo.card2SaveOffset + set->romInfo.saveSize;
|
||||
else
|
||||
cciUsedSize = set->romInfo.usedSize;
|
||||
|
||||
if(cciUsedSize > set->romInfo.mediaSize){
|
||||
fprintf(stderr,"[CCI ERROR] MediaSize '%s' is insufficient for the CCI data\n",GetMediaSizeStr(set->romInfo.mediaSize));
|
||||
return CCI_CONFIG_FAIL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WriteCciDataToOutput(cci_settings *set)
|
||||
{
|
||||
if (set->options.verbose) {
|
||||
printf("[CCI] Writing header to file... ");
|
||||
}
|
||||
|
||||
// NCSD Header
|
||||
WriteBuffer(set->headers.ccihdr.buffer, set->headers.ccihdr.size, 0, set->out);
|
||||
// Card Info Header
|
||||
WriteBuffer(set->headers.cardinfohdr.buffer, set->headers.cardinfohdr.size, set->headers.ccihdr.size, set->out);
|
||||
|
||||
// Dummy data between header and first NCCH
|
||||
u64 len = set->content.cOffset[0] - (set->headers.ccihdr.size + set->headers.cardinfohdr.size);
|
||||
u8 *dummy_data = malloc(len);
|
||||
if(set->headers.cardinfohdr.size > sizeof(cardinfo_hdr)) // additional debug header data exists
|
||||
memset(dummy_data, 0x00, len);
|
||||
else // normal production cci image
|
||||
memset(dummy_data, 0xff, len);
|
||||
WriteBuffer(dummy_data, len, (set->headers.ccihdr.size + set->headers.cardinfohdr.size),set->out);
|
||||
free(dummy_data);
|
||||
|
||||
if (set->options.verbose) {
|
||||
printf("Done!\n");
|
||||
}
|
||||
|
||||
// NCCH Partitions
|
||||
u8 *ncch;
|
||||
for(int i = 0; i < CCI_MAX_CONTENT; i++){
|
||||
if(set->content.active[i]){
|
||||
if (set->options.verbose) {
|
||||
printf("[CCI] Writing content %d to file... ", i);
|
||||
}
|
||||
|
||||
ncch = set->content.data + set->content.dOffset[i];
|
||||
WriteBuffer(ncch, set->content.dSize[i], set->content.cOffset[i], set->out);
|
||||
|
||||
if (set->options.verbose) {
|
||||
printf("Done!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cci Padding
|
||||
if(set->options.padCci){
|
||||
if (set->options.verbose) {
|
||||
printf("[CCI] Writing padding to file... ");
|
||||
}
|
||||
|
||||
fseek_64(set->out,set->romInfo.usedSize);
|
||||
|
||||
// Determining Size of Padding
|
||||
u64 len = set->romInfo.mediaSize - set->romInfo.usedSize;
|
||||
|
||||
// Create Padding chunk
|
||||
u8 *pad = malloc(set->romInfo.blockSize);
|
||||
memset(pad,0xff,set->romInfo.blockSize);
|
||||
|
||||
// Writing Dummy Bytes to file
|
||||
for(u64 i = 0; i < len; i += set->romInfo.blockSize)
|
||||
fwrite(pad,set->romInfo.blockSize,1,set->out);
|
||||
|
||||
free(pad);
|
||||
|
||||
if (set->options.verbose) {
|
||||
printf("Done!");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool IsCci(u8 *ncsd)
|
||||
{
|
||||
cci_hdr *hdr = (cci_hdr*)ncsd;
|
||||
if(!hdr) return false;
|
||||
if(memcmp(hdr->magic,"NCSD",4)!=0) return false;
|
||||
if(hdr->flags[cciflag_MEDIA_PLATFORM] != cciplatform_CTR) return false;
|
||||
if(hdr->flags[cciflag_MEDIA_TYPE] != mediatype_CARD1 && hdr->flags[cciflag_MEDIA_TYPE] != mediatype_CARD2) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 GetPartitionOffset(u8 *ncsd, u8 index)
|
||||
{
|
||||
cci_hdr *hdr = (cci_hdr*)ncsd;
|
||||
return (u64)u8_to_u64(hdr->offset_sizeTable[index].offset,LE) * (u64)GetCtrBlockSize(hdr->flags[cciflag_MEDIA_BLOCK_SIZE]);
|
||||
}
|
||||
|
||||
u64 GetPartitionSize(u8 *ncsd, u8 index)
|
||||
{
|
||||
cci_hdr *hdr = (cci_hdr*)ncsd;
|
||||
return (u64)u8_to_u64(hdr->offset_sizeTable[index].size,LE) * (u64)GetCtrBlockSize(hdr->flags[cciflag_MEDIA_BLOCK_SIZE]);
|
||||
}
|
||||
|
||||
u8* GetPartition(u8 *ncsd, u8 index)
|
||||
{
|
||||
return ncsd + GetPartitionOffset(ncsd,index);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum
|
||||
{
|
||||
cciflag_BACKUP_WRITE_WAIT_TIME = 0,
|
||||
cciflag_FW6_SAVE_CRYPTO = 1,
|
||||
cciflag_CARD_DEVICE = 3,
|
||||
cciflag_MEDIA_PLATFORM = 4,
|
||||
cciflag_MEDIA_TYPE = 5,
|
||||
cciflag_MEDIA_BLOCK_SIZE = 6,
|
||||
cciflag_CARD_DEVICE_OLD = 7
|
||||
} cci_flagindex;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
carddevice_NOR_FLASH = 1,
|
||||
carddevice_NONE = 2,
|
||||
carddevice_BT = 3
|
||||
} cci_carddevice;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
cciplatform_CTR = 1,
|
||||
} cci_platform;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
mediatype_INNER_DEVICE, // NAND
|
||||
mediatype_CARD1,
|
||||
mediatype_CARD2,
|
||||
mediatype_EXTENDED_DEVICE
|
||||
} cci_mediatype;
|
||||
|
||||
// Structs
|
||||
typedef struct
|
||||
{
|
||||
u8 offset[4];
|
||||
u8 size[4];
|
||||
} ncch_offsetsize;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 signature[0x100];
|
||||
u8 magic[4];
|
||||
u8 mediaSize[4];
|
||||
u8 titleId[8];
|
||||
u8 padding0[0x10];
|
||||
ncch_offsetsize offset_sizeTable[8];
|
||||
u8 padding1[0x28];
|
||||
u8 flags[8];
|
||||
u8 ncchIdTable[8][8];
|
||||
u8 padding2[0x30];
|
||||
} cci_hdr;
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
#include "ncsd.h"
|
||||
#include "tmd_read.h"
|
||||
|
||||
|
||||
// Enums
|
||||
typedef enum
|
||||
{
|
||||
NCSD_NO_NCCH0 = -1,
|
||||
NCSD_INVALID_NCCH0 = -2,
|
||||
NCSD_INVALID_NCCH = -3,
|
||||
INVALID_RSF_OPT = -4,
|
||||
GEN_HDR_FAIL = -5,
|
||||
INCOMPAT_CIA = -6,
|
||||
CCI_CONFIG_FAIL = -7,
|
||||
} ncsd_errors;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
rsf_settings *rsf;
|
||||
keys_struct *keys;
|
||||
|
||||
FILE *out;
|
||||
|
||||
struct{
|
||||
bool verbose;
|
||||
bool padCci;
|
||||
bool noModTid;
|
||||
bool useExternalSdkCardInfo;
|
||||
bool closeAlignWR;
|
||||
|
||||
u8 cverDataType;
|
||||
char *cverDataPath;
|
||||
tmd_hdr *tmdHdr;
|
||||
} options;
|
||||
|
||||
struct{
|
||||
u32 blockSize;
|
||||
|
||||
u64 mediaSize;
|
||||
u64 usedSize;
|
||||
|
||||
u8 mediaType;
|
||||
u8 cardDevice;
|
||||
u64 saveSize;
|
||||
u64 card2SaveOffset;
|
||||
} romInfo;
|
||||
|
||||
struct{
|
||||
u8 *data;
|
||||
u64 dataLen;
|
||||
infile_type dataType;
|
||||
|
||||
char **path;
|
||||
|
||||
bool active[CCI_MAX_CONTENT];
|
||||
u64 dOffset[CCI_MAX_CONTENT];
|
||||
u64 *dSize;
|
||||
u64 titleId[CCI_MAX_CONTENT];
|
||||
|
||||
u64 cOffset[CCI_MAX_CONTENT];
|
||||
} content;
|
||||
|
||||
struct{
|
||||
buffer_struct ccihdr;
|
||||
buffer_struct cardinfohdr;
|
||||
} headers;
|
||||
} cci_settings;
|
||||
|
||||
// Public Prototypes
|
||||
// Build Functions
|
||||
int build_CCI(user_settings *usrset);
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "ncsd.h"
|
||||
|
||||
// Read Functions
|
||||
bool IsCci(u8 *ncsd);
|
||||
u8* GetPartition(u8 *ncsd, u8 index);
|
||||
u64 GetPartitionOffset(u8 *ncsd, u8 index);
|
||||
u64 GetPartitionSize(u8 *ncsd, u8 index);
|
||||
@@ -0,0 +1,210 @@
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#ifndef __CYGWIN__
|
||||
#define LIBICONV_PLUG
|
||||
#endif
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
#include "oschar.h"
|
||||
|
||||
int os_fstat(const oschar_t *path)
|
||||
{
|
||||
struct _osstat st;
|
||||
return os_stat(path, &st);
|
||||
}
|
||||
|
||||
uint64_t os_fsize(const oschar_t *path)
|
||||
{
|
||||
struct _osstat st;
|
||||
if (os_stat(path, &st) != 0)
|
||||
return 0;
|
||||
else
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
int os_makedir(const oschar_t *dir)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _wmkdir(dir);
|
||||
#else
|
||||
return mkdir(dir, 0777);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t utf16_strlen(const utf16char_t *str)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; str[i] != 0x0; i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
void utf16_fputs(const utf16char_t *str, FILE *out)
|
||||
{
|
||||
oschar_t *_str = os_CopyConvertUTF16Str(str);
|
||||
os_fputs(_str, out);
|
||||
free(_str);
|
||||
}
|
||||
|
||||
char* strcopy_8to8(const char *src)
|
||||
{
|
||||
uint32_t src_len;
|
||||
char *dst;
|
||||
|
||||
if (!src)
|
||||
return NULL;
|
||||
|
||||
src_len = strlen(src);
|
||||
|
||||
// Allocate memory for expanded string
|
||||
dst = calloc(src_len + 1, sizeof(char));
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
// Copy elements from src into dst
|
||||
strncpy(dst, src, src_len);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
utf16char_t* strcopy_8to16(const char *src)
|
||||
{
|
||||
uint32_t src_len, i;
|
||||
utf16char_t *dst;
|
||||
|
||||
if (!src)
|
||||
return NULL;
|
||||
|
||||
src_len = strlen(src);
|
||||
|
||||
// Allocate memory for expanded string
|
||||
dst = calloc(src_len + 1, sizeof(utf16char_t));
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
// Copy elements from src into dst
|
||||
for (i = 0; i < src_len; i++)
|
||||
dst[i] = src[i];
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
utf16char_t* strcopy_16to16(const utf16char_t *src)
|
||||
{
|
||||
uint32_t src_len, i;
|
||||
utf16char_t *dst;
|
||||
|
||||
if (!src)
|
||||
return NULL;
|
||||
|
||||
src_len = utf16_strlen(src);
|
||||
|
||||
// Allocate memory for expanded string
|
||||
dst = calloc(src_len + 1, sizeof(utf16char_t));
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
// Copy elements from src into dst
|
||||
for (i = 0; i < src_len; i++)
|
||||
dst[i] = src[i];
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
utf16char_t* strcopy_UTF8toUTF16(const char *src)
|
||||
{
|
||||
uint32_t src_len, dst_len;
|
||||
size_t in_bytes, out_bytes;
|
||||
utf16char_t *dst;
|
||||
char *in, *out;
|
||||
|
||||
if (!src)
|
||||
return NULL;
|
||||
|
||||
src_len = strlen(src);
|
||||
dst_len = src_len + 1;
|
||||
|
||||
// Allocate memory for string
|
||||
dst = calloc(dst_len, sizeof(utf16char_t));
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
in = (char*)src;
|
||||
out = (char*)dst;
|
||||
in_bytes = src_len*sizeof(char);
|
||||
out_bytes = dst_len*sizeof(utf16char_t);
|
||||
|
||||
iconv_t cd = iconv_open("UTF-16LE", "UTF-8");
|
||||
iconv(cd, &in, &in_bytes, &out, &out_bytes);
|
||||
iconv_close(cd);
|
||||
return dst;
|
||||
}
|
||||
|
||||
char* strcopy_UTF16toUTF8(const utf16char_t *src)
|
||||
{
|
||||
uint32_t src_len, dst_len;
|
||||
size_t in_bytes, out_bytes;
|
||||
char *dst;
|
||||
char *in, *out;
|
||||
|
||||
if (!src)
|
||||
return NULL;
|
||||
|
||||
src_len = utf16_strlen(src);
|
||||
// UTF-8 can use up to 3 bytes per UTF-16 code unit, or four for a surrogate pair
|
||||
dst_len = src_len * 3;
|
||||
|
||||
// Allocate memory for string
|
||||
dst = calloc(dst_len, sizeof(char));
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
in = (char*)src;
|
||||
out = (char*)dst;
|
||||
in_bytes = src_len*sizeof(uint16_t);
|
||||
out_bytes = dst_len*sizeof(char);
|
||||
|
||||
iconv_t cd = iconv_open("UTF-8", "UTF-16LE");
|
||||
iconv(cd, &in, &in_bytes, &out, &out_bytes);
|
||||
iconv_close(cd);
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
oschar_t* os_AppendToPath(const oschar_t *src, const oschar_t *add)
|
||||
{
|
||||
uint32_t len;
|
||||
oschar_t *new_path;
|
||||
|
||||
len = os_strlen(src) + os_strlen(add) + 0x10;
|
||||
new_path = calloc(len, sizeof(oschar_t));
|
||||
|
||||
#ifdef _WIN32
|
||||
_snwprintf(new_path, len, L"%s%c%s", src, OS_PATH_SEPARATOR, add);
|
||||
#else
|
||||
snprintf(new_path, len, "%s%c%s", src, OS_PATH_SEPARATOR, add);
|
||||
#endif
|
||||
|
||||
return new_path;
|
||||
}
|
||||
|
||||
oschar_t* os_AppendUTF16StrToPath(const oschar_t *src, const utf16char_t *add)
|
||||
{
|
||||
uint32_t len;
|
||||
oschar_t *new_path, *_add;
|
||||
|
||||
_add = os_CopyConvertUTF16Str(add);
|
||||
|
||||
len = os_strlen(src) + os_strlen(_add) + 0x10;
|
||||
new_path = calloc(len, sizeof(oschar_t));
|
||||
|
||||
#ifdef _WIN32
|
||||
_snwprintf(new_path, len, L"%s%c%s", src, OS_PATH_SEPARATOR, _add);
|
||||
#else
|
||||
snprintf(new_path, len, "%s%c%s", src, OS_PATH_SEPARATOR, _add);
|
||||
#endif
|
||||
|
||||
free(_add);
|
||||
return new_path;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
// Nintendo uses UTF16-LE chars for extended ASCII support
|
||||
typedef uint16_t utf16char_t;
|
||||
|
||||
// Native OS char type for unicode support
|
||||
#ifdef _WIN32
|
||||
typedef wchar_t oschar_t; // UTF16-LE
|
||||
#else
|
||||
typedef char oschar_t; // UTF8
|
||||
#endif
|
||||
|
||||
// Simple redirect macros for functions and types
|
||||
#ifdef _WIN32
|
||||
#define os_strlen wcslen
|
||||
#define os_strcmp wcscmp
|
||||
#define os_fputs fputws
|
||||
|
||||
#define os_CopyStr strcopy_16to16
|
||||
#define os_CopyConvertCharStr strcopy_8to16
|
||||
#define os_CopyConvertUTF16Str strcopy_16to16
|
||||
#define utf16_CopyStr strcopy_16to16
|
||||
#define utf16_CopyConvertOsStr strcopy_16to16
|
||||
|
||||
#define _osdirent _wdirent
|
||||
#define _OSDIR _WDIR
|
||||
#define os_readdir _wreaddir
|
||||
#define os_opendir _wopendir
|
||||
#define os_closedir _wclosedir
|
||||
#define os_chdir _wchdir
|
||||
|
||||
#define _osstat _stat64
|
||||
#define os_stat _wstat64
|
||||
|
||||
#define os_fopen _wfopen
|
||||
#define OS_MODE_READ L"rb"
|
||||
#define OS_MODE_WRITE L"wb"
|
||||
#define OS_MODE_EDIT L"rb+"
|
||||
#define OS_PATH_SEPARATOR '\\'
|
||||
#else
|
||||
#define os_strlen strlen
|
||||
#define os_strcmp strcmp
|
||||
#define os_fputs fputs
|
||||
|
||||
#define os_CopyStr strcopy_8to8
|
||||
#define os_CopyConvertUTF16Str strcopy_UTF16toUTF8
|
||||
#define os_CopyConvertCharStr strcopy_8to8
|
||||
#define utf16_CopyStr strcopy_16to16
|
||||
#define utf16_CopyConvertOsStr strcopy_UTF8toUTF16
|
||||
|
||||
#define _osdirent dirent
|
||||
#define _OSDIR DIR
|
||||
#define os_readdir readdir
|
||||
#define os_opendir opendir
|
||||
#define os_closedir closedir
|
||||
#define os_chdir chdir
|
||||
|
||||
#define _osstat stat
|
||||
#define os_stat stat
|
||||
|
||||
#define os_fopen fopen
|
||||
#define OS_MODE_READ "rb"
|
||||
#define OS_MODE_WRITE "wb"
|
||||
#define OS_MODE_EDIT "rb+"
|
||||
#define OS_PATH_SEPARATOR '/'
|
||||
#endif
|
||||
|
||||
/* File related */
|
||||
int os_fstat(const oschar_t* path);
|
||||
uint64_t os_fsize(const oschar_t* path);
|
||||
int os_makedir(const oschar_t *dir);
|
||||
|
||||
/* UTF16 String property functions */
|
||||
uint32_t utf16_strlen(const utf16char_t* str);
|
||||
void utf16_fputs(const utf16char_t *str, FILE *out);
|
||||
|
||||
/* String Copy and Conversion */
|
||||
char* strcopy_8to8(const char *src);
|
||||
utf16char_t* strcopy_8to16(const char *src);
|
||||
utf16char_t* strcopy_16to16(const utf16char_t *src);
|
||||
#ifndef _WIN32
|
||||
utf16char_t* strcopy_UTF8toUTF16(const char *src);
|
||||
char* strcopy_UTF16toUTF8(const utf16char_t *src);
|
||||
#endif
|
||||
|
||||
/* String Append and Create */
|
||||
oschar_t* os_AppendToPath(const oschar_t *src, const oschar_t *add);
|
||||
oschar_t* os_AppendUTF16StrToPath(const oschar_t *src, const utf16char_t *add);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
// AES Keys
|
||||
static const unsigned char rvl_common_etd_key_ppki[2][16] =
|
||||
{
|
||||
{0xEB, 0xE4, 0x2A, 0x22, 0x5E, 0x85, 0x93, 0xE4, 0x48, 0xD9, 0xC5, 0x45, 0x73, 0x81, 0xAA, 0xF7} , // 0 - Normal
|
||||
{0x63, 0xB8, 0x2B, 0xB4, 0xF4, 0x61, 0x4E, 0x2E, 0x13, 0xF2, 0xFE, 0xFB, 0xBA, 0x4C, 0x9B, 0x7E} , // 1 - Korean
|
||||
};
|
||||
|
||||
static const unsigned char twl_common_etd_key_ppki[1][16] =
|
||||
{
|
||||
{0xAF, 0x1B, 0xF5, 0x16, 0xA8, 0x07, 0xD2, 0x1A, 0xEA, 0x45, 0x98, 0x4F, 0x04, 0x74, 0x28, 0x61} , // 0 - Normal
|
||||
};
|
||||
|
||||
// RSA Keys
|
||||
|
||||
// Certificates
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct CtrRsa2048Key {
|
||||
uint8_t modulus[0x100];
|
||||
uint8_t priv_exponent[0x100];
|
||||
//uint8_t pub_exponent[0x3];
|
||||
} CtrRsa2048Key;
|
||||
|
||||
typedef struct CtrRsa4096Key {
|
||||
uint8_t modulus[0x200];
|
||||
uint8_t priv_exponent[0x200];
|
||||
//uint8_t pub_exponent[0x3];
|
||||
} CtrRsa4096Key;
|
||||
@@ -0,0 +1,349 @@
|
||||
#pragma once
|
||||
#include "rsa_key.h"
|
||||
|
||||
// AES KEYS
|
||||
static const unsigned char zeros_aesKey[16] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// RSA KEYS
|
||||
static const CtrRsa2048Key tpki_rsa =
|
||||
{
|
||||
.modulus = { 0xCA, 0xC5, 0x88, 0xC7, 0xF1, 0x2A, 0x09, 0x2B, 0x76, 0x49, 0xC0, 0xA8, 0x35, 0x75, 0x10, 0x82, 0xC2, 0xB5, 0xE5, 0xB2, 0xE9, 0xC8, 0x18, 0x88, 0xF3, 0x98, 0x89, 0xBF, 0x9D, 0xE6, 0xE4, 0x0B, 0x71, 0x5D, 0xDD, 0x3F, 0x13, 0x82, 0x71, 0xF2, 0xED, 0x31, 0x86, 0x99, 0xD9, 0x47, 0xFE, 0xC5, 0x7A, 0x75, 0x93, 0xE1, 0xF8, 0x6D, 0xC6, 0x3D, 0x9B, 0xE1, 0x15, 0x99, 0xE1, 0xC2, 0xE0, 0x5C, 0x38, 0x4B, 0x35, 0xA2, 0x4D, 0x3E, 0xE2, 0xCE, 0xFB, 0xB3, 0x08, 0xA3, 0xDD, 0x0C, 0x26, 0x31, 0x84, 0x92, 0x27, 0xC8, 0x8A, 0x8E, 0xC8, 0x83, 0xA8, 0x6C, 0xA7, 0xA3, 0x39, 0x71, 0x9E, 0xF1, 0x34, 0x91, 0x01, 0xDF, 0x11, 0x4A, 0x9C, 0xF9, 0x8B, 0xF9, 0x2F, 0x46, 0x44, 0x0A, 0x72, 0x38, 0xF3, 0x8B, 0x6D, 0x23, 0x33, 0x89, 0xBF, 0x66, 0x34, 0xA7, 0x86, 0xE6, 0xAD, 0xF2, 0xDE, 0xF9, 0xAB, 0x16, 0xA1, 0x40, 0xEE, 0xD8, 0xF7, 0x6C, 0xDC, 0x00, 0x92, 0xCB, 0x31, 0x49, 0xFC, 0x26, 0x64, 0x24, 0x08, 0x8F, 0xC6, 0x60, 0xFF, 0x1E, 0xE3, 0xF0, 0xDD, 0xFB, 0x6D, 0x0D, 0x0F, 0x49, 0x7C, 0xAD, 0x03, 0xEC, 0x9F, 0x63, 0x58, 0xFA, 0x46, 0xDF, 0xA2, 0x64, 0x0E, 0xCC, 0x85, 0x57, 0xE7, 0x2C, 0x61, 0x7F, 0x59, 0xB8, 0x62, 0x7D, 0x59, 0x0E, 0xF6, 0x84, 0x96, 0x99, 0x42, 0xB0, 0x39, 0x83, 0x80, 0xB5, 0x52, 0x2E, 0x07, 0x3F, 0x92, 0xE3, 0x9E, 0xF5, 0x47, 0xEB, 0xA7, 0xD7, 0xD4, 0x15, 0xF1, 0x22, 0x82, 0x32, 0xBE, 0x2A, 0xD0, 0x8C, 0x01, 0xCC, 0x30, 0xA9, 0x11, 0x96, 0xF6, 0xE9, 0x2B, 0xEA, 0x0E, 0xF8, 0x2D, 0x0D, 0xB1, 0x91, 0xD5, 0x1A, 0x94, 0x51, 0xB9, 0x85, 0x39, 0xB0, 0xAF, 0x9F, 0x54, 0x9E, 0x99, 0xE1, 0x46, 0xE5, 0x6F, 0xE2, 0x5F, 0x4B, 0x4E, 0x23 },
|
||||
.priv_exponent = { 0x3E, 0x2B, 0xBE, 0xBA, 0x7F, 0x29, 0x02, 0x52, 0xBF, 0x1B, 0xF1, 0xE4, 0x21, 0x2F, 0xD9, 0x76, 0x1E, 0x39, 0x23, 0x4A, 0x6D, 0xFF, 0x99, 0xF6, 0x33, 0xAA, 0x2B, 0x62, 0x03, 0x0A, 0x0E, 0x15, 0xAC, 0x16, 0xB9, 0x85, 0x63, 0x77, 0xF5, 0x74, 0x24, 0x61, 0xB1, 0x01, 0x6E, 0xEB, 0x72, 0x24, 0x1E, 0x5D, 0xFA, 0x8F, 0xA8, 0x5A, 0x10, 0x14, 0x47, 0xBD, 0x05, 0xA0, 0x7E, 0xE5, 0xFF, 0x60, 0x87, 0x2A, 0x18, 0x31, 0xC1, 0x39, 0x6C, 0xD5, 0x45, 0xBB, 0x29, 0x05, 0x04, 0xFB, 0x7A, 0xA2, 0x68, 0x21, 0x5F, 0xED, 0x4E, 0xFE, 0x64, 0x60, 0x69, 0xBD, 0x96, 0xD0, 0xA7, 0x06, 0x3D, 0x53, 0x7B, 0x68, 0x92, 0x88, 0x50, 0x86, 0xEE, 0x06, 0x5D, 0x72, 0x73, 0x9A, 0x39, 0xB6, 0x72, 0x3B, 0x20, 0x01, 0x39, 0xDF, 0x37, 0x28, 0x1E, 0xF5, 0x39, 0x63, 0xBC, 0x2A, 0xF2, 0x5E, 0xAB, 0x1A, 0x99, 0xE4, 0x5B, 0xEB, 0xE6, 0x36, 0x30, 0x6C, 0x40, 0x01, 0x61, 0x60, 0xCC, 0x55, 0x89, 0x6D, 0xCA, 0x7E, 0xE0, 0x64, 0x78, 0x7F, 0x7B, 0x26, 0xAE, 0x3E, 0xA3, 0x12, 0x45, 0x16, 0xF6, 0xC8, 0xD0, 0xB9, 0x4F, 0x91, 0x11, 0x12, 0x11, 0xBB, 0xBB, 0x7F, 0xAB, 0xC7, 0x82, 0xDC, 0x4A, 0x61, 0x9C, 0x14, 0xAE, 0x29, 0xFD, 0x3A, 0x60, 0x13, 0x93, 0x19, 0x2F, 0x54, 0x49, 0xB2, 0x44, 0x34, 0x58, 0x14, 0xD7, 0x2F, 0x70, 0x25, 0xA0, 0x48, 0x66, 0x76, 0x55, 0x87, 0x9B, 0x25, 0x77, 0x6D, 0x0B, 0x75, 0x98, 0x8B, 0xA6, 0x39, 0x40, 0x3C, 0x21, 0x7F, 0x2A, 0x24, 0xC1, 0xA5, 0xC1, 0xDC, 0x5A, 0x57, 0x54, 0xF6, 0x03, 0xF6, 0xAD, 0x51, 0x33, 0x40, 0x6D, 0x5C, 0x26, 0x5E, 0x29, 0x92, 0x82, 0xE5, 0x29, 0x13, 0x7D, 0x7D, 0xFE, 0x08, 0x73, 0xBC, 0x5D, 0xC4, 0xE9, 0x2B, 0xD6, 0x71 }
|
||||
};
|
||||
|
||||
//Certificates
|
||||
static const unsigned char ca3_tpki_cert[0x400] =
|
||||
{
|
||||
0x00, 0x01, 0x00, 0x03, 0x70, 0x41, 0x38, 0xEF,
|
||||
0xBB, 0xBD, 0xA1, 0x6A, 0x98, 0x7D, 0xD9, 0x01,
|
||||
0x32, 0x6D, 0x1C, 0x94, 0x59, 0x48, 0x4C, 0x88,
|
||||
0xA2, 0x86, 0x1B, 0x91, 0xA3, 0x12, 0x58, 0x7A,
|
||||
0xE7, 0x0E, 0xF6, 0x23, 0x7E, 0xC5, 0x0E, 0x10,
|
||||
0x32, 0xDC, 0x39, 0xDD, 0xE8, 0x9A, 0x96, 0xA8,
|
||||
0xE8, 0x59, 0xD7, 0x6A, 0x98, 0xA6, 0xE7, 0xE3,
|
||||
0x6A, 0x0C, 0xFE, 0x35, 0x2C, 0xA8, 0x93, 0x05,
|
||||
0x82, 0x34, 0xFF, 0x83, 0x3F, 0xCB, 0x3B, 0x03,
|
||||
0x81, 0x1E, 0x9F, 0x0D, 0xC0, 0xD9, 0xA5, 0x2F,
|
||||
0x80, 0x45, 0xB4, 0xB2, 0xF9, 0x41, 0x1B, 0x67,
|
||||
0xA5, 0x1C, 0x44, 0xB5, 0xEF, 0x8C, 0xE7, 0x7B,
|
||||
0xD6, 0xD5, 0x6B, 0xA7, 0x57, 0x34, 0xA1, 0x85,
|
||||
0x6D, 0xE6, 0xD4, 0xBE, 0xD6, 0xD3, 0xA2, 0x42,
|
||||
0xC7, 0xC8, 0x79, 0x1B, 0x34, 0x22, 0x37, 0x5E,
|
||||
0x5C, 0x77, 0x9A, 0xBF, 0x07, 0x2F, 0x76, 0x95,
|
||||
0xEF, 0xA0, 0xF7, 0x5B, 0xCB, 0x83, 0x78, 0x9F,
|
||||
0xC3, 0x0E, 0x3F, 0xE4, 0xCC, 0x83, 0x92, 0x20,
|
||||
0x78, 0x40, 0x63, 0x89, 0x49, 0xC7, 0xF6, 0x88,
|
||||
0x56, 0x5F, 0x64, 0x9B, 0x74, 0xD6, 0x3D, 0x8D,
|
||||
0x58, 0xFF, 0xAD, 0xDA, 0x57, 0x1E, 0x95, 0x54,
|
||||
0x42, 0x6B, 0x13, 0x18, 0xFC, 0x46, 0x89, 0x83,
|
||||
0xD4, 0xC8, 0xA5, 0x62, 0x8B, 0x06, 0xB6, 0xFC,
|
||||
0x5D, 0x50, 0x7C, 0x13, 0xE7, 0xA1, 0x8A, 0xC1,
|
||||
0x51, 0x1E, 0xB6, 0xD6, 0x2E, 0xA5, 0x44, 0x8F,
|
||||
0x83, 0x50, 0x14, 0x47, 0xA9, 0xAF, 0xB3, 0xEC,
|
||||
0xC2, 0x90, 0x3C, 0x9D, 0xD5, 0x2F, 0x92, 0x2A,
|
||||
0xC9, 0xAC, 0xDB, 0xEF, 0x58, 0xC6, 0x02, 0x18,
|
||||
0x48, 0xD9, 0x6E, 0x20, 0x87, 0x32, 0xD3, 0xD1,
|
||||
0xD9, 0xD9, 0xEA, 0x44, 0x0D, 0x91, 0x62, 0x1C,
|
||||
0x7A, 0x99, 0xDB, 0x88, 0x43, 0xC5, 0x9C, 0x1F,
|
||||
0x2E, 0x2C, 0x7D, 0x9B, 0x57, 0x7D, 0x51, 0x2C,
|
||||
0x16, 0x6D, 0x6F, 0x7E, 0x1A, 0xAD, 0x4A, 0x77,
|
||||
0x4A, 0x37, 0x44, 0x7E, 0x78, 0xFE, 0x20, 0x21,
|
||||
0xE1, 0x4A, 0x95, 0xD1, 0x12, 0xA0, 0x68, 0xAD,
|
||||
0xA0, 0x19, 0xF4, 0x63, 0xC7, 0xA5, 0x56, 0x85,
|
||||
0xAA, 0xBB, 0x68, 0x88, 0xB9, 0x24, 0x64, 0x83,
|
||||
0xD1, 0x8B, 0x9C, 0x80, 0x6F, 0x47, 0x49, 0x18,
|
||||
0x33, 0x17, 0x82, 0x34, 0x4A, 0x4B, 0x85, 0x31,
|
||||
0x33, 0x4B, 0x26, 0x30, 0x32, 0x63, 0xD9, 0xD2,
|
||||
0xEB, 0x4F, 0x4B, 0xB9, 0x96, 0x02, 0xB3, 0x52,
|
||||
0xF6, 0xAE, 0x40, 0x46, 0xC6, 0x9A, 0x5E, 0x7E,
|
||||
0x8E, 0x4A, 0x18, 0xEF, 0x9B, 0xC0, 0xA2, 0xDE,
|
||||
0xD6, 0x13, 0x10, 0x41, 0x70, 0x12, 0xFD, 0x82,
|
||||
0x4C, 0xC1, 0x16, 0xCF, 0xB7, 0xC4, 0xC1, 0xF7,
|
||||
0xEC, 0x71, 0x77, 0xA1, 0x74, 0x46, 0xCB, 0xDE,
|
||||
0x96, 0xF3, 0xED, 0xD8, 0x8F, 0xCD, 0x05, 0x2F,
|
||||
0x0B, 0x88, 0x8A, 0x45, 0xFD, 0xAF, 0x2B, 0x63,
|
||||
0x13, 0x54, 0xF4, 0x0D, 0x16, 0xE5, 0xFA, 0x9C,
|
||||
0x2C, 0x4E, 0xDA, 0x98, 0xE7, 0x98, 0xD1, 0x5E,
|
||||
0x60, 0x46, 0xDC, 0x53, 0x63, 0xF3, 0x09, 0x6B,
|
||||
0x2C, 0x60, 0x7A, 0x9D, 0x8D, 0xD5, 0x5B, 0x15,
|
||||
0x02, 0xA6, 0xAC, 0x7D, 0x3C, 0xC8, 0xD8, 0xC5,
|
||||
0x75, 0x99, 0x8E, 0x7D, 0x79, 0x69, 0x10, 0xC8,
|
||||
0x04, 0xC4, 0x95, 0x23, 0x50, 0x57, 0xE9, 0x1E,
|
||||
0xCD, 0x26, 0x37, 0xC9, 0xC1, 0x84, 0x51, 0x51,
|
||||
0xAC, 0x6B, 0x9A, 0x04, 0x90, 0xAE, 0x3E, 0xC6,
|
||||
0xF4, 0x77, 0x40, 0xA0, 0xDB, 0x0B, 0xA3, 0x6D,
|
||||
0x07, 0x59, 0x56, 0xCE, 0xE7, 0x35, 0x4E, 0xA3,
|
||||
0xE9, 0xA4, 0xF2, 0x72, 0x0B, 0x26, 0x55, 0x0C,
|
||||
0x7D, 0x39, 0x43, 0x24, 0xBC, 0x0C, 0xB7, 0xE9,
|
||||
0x31, 0x7D, 0x8A, 0x86, 0x61, 0xF4, 0x21, 0x91,
|
||||
0xFF, 0x10, 0xB0, 0x82, 0x56, 0xCE, 0x3F, 0xD2,
|
||||
0x5B, 0x74, 0x5E, 0x51, 0x94, 0x90, 0x6B, 0x4D,
|
||||
0x61, 0xCB, 0x4C, 0x2E, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x52, 0x6F, 0x6F, 0x74, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x43, 0x41, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7B, 0xE8, 0xEF, 0x6C,
|
||||
0xB2, 0x79, 0xC9, 0xE2, 0xEE, 0xE1, 0x21, 0xC6,
|
||||
0xEA, 0xF4, 0x4F, 0xF6, 0x39, 0xF8, 0x8F, 0x07,
|
||||
0x8B, 0x4B, 0x77, 0xED, 0x9F, 0x95, 0x60, 0xB0,
|
||||
0x35, 0x82, 0x81, 0xB5, 0x0E, 0x55, 0xAB, 0x72,
|
||||
0x11, 0x15, 0xA1, 0x77, 0x70, 0x3C, 0x7A, 0x30,
|
||||
0xFE, 0x3A, 0xE9, 0xEF, 0x1C, 0x60, 0xBC, 0x1D,
|
||||
0x97, 0x46, 0x76, 0xB2, 0x3A, 0x68, 0xCC, 0x04,
|
||||
0xB1, 0x98, 0x52, 0x5B, 0xC9, 0x68, 0xF1, 0x1D,
|
||||
0xE2, 0xDB, 0x50, 0xE4, 0xD9, 0xE7, 0xF0, 0x71,
|
||||
0xE5, 0x62, 0xDA, 0xE2, 0x09, 0x22, 0x33, 0xE9,
|
||||
0xD3, 0x63, 0xF6, 0x1D, 0xD7, 0xC1, 0x9F, 0xF3,
|
||||
0xA4, 0xA9, 0x1E, 0x8F, 0x65, 0x53, 0xD4, 0x71,
|
||||
0xDD, 0x7B, 0x84, 0xB9, 0xF1, 0xB8, 0xCE, 0x73,
|
||||
0x35, 0xF0, 0xF5, 0x54, 0x05, 0x63, 0xA1, 0xEA,
|
||||
0xB8, 0x39, 0x63, 0xE0, 0x9B, 0xE9, 0x01, 0x01,
|
||||
0x1F, 0x99, 0x54, 0x63, 0x61, 0x28, 0x70, 0x20,
|
||||
0xE9, 0xCC, 0x0D, 0xAB, 0x48, 0x7F, 0x14, 0x0D,
|
||||
0x66, 0x26, 0xA1, 0x83, 0x6D, 0x27, 0x11, 0x1F,
|
||||
0x20, 0x68, 0xDE, 0x47, 0x72, 0x14, 0x91, 0x51,
|
||||
0xCF, 0x69, 0xC6, 0x1B, 0xA6, 0x0E, 0xF9, 0xD9,
|
||||
0x49, 0xA0, 0xF7, 0x1F, 0x54, 0x99, 0xF2, 0xD3,
|
||||
0x9A, 0xD2, 0x8C, 0x70, 0x05, 0x34, 0x82, 0x93,
|
||||
0xC4, 0x31, 0xFF, 0xBD, 0x33, 0xF6, 0xBC, 0xA6,
|
||||
0x0D, 0xC7, 0x19, 0x5E, 0xA2, 0xBC, 0xC5, 0x6D,
|
||||
0x20, 0x0B, 0xAF, 0x6D, 0x06, 0xD0, 0x9C, 0x41,
|
||||
0xDB, 0x8D, 0xE9, 0xC7, 0x20, 0x15, 0x4C, 0xA4,
|
||||
0x83, 0x2B, 0x69, 0xC0, 0x8C, 0x69, 0xCD, 0x3B,
|
||||
0x07, 0x3A, 0x00, 0x63, 0x60, 0x2F, 0x46, 0x2D,
|
||||
0x33, 0x80, 0x61, 0xA5, 0xEA, 0x6C, 0x91, 0x5C,
|
||||
0xD5, 0x62, 0x35, 0x79, 0xC3, 0xEB, 0x64, 0xCE,
|
||||
0x44, 0xEF, 0x58, 0x6D, 0x14, 0xBA, 0xAA, 0x88,
|
||||
0x34, 0x01, 0x9B, 0x3E, 0xEB, 0xEE, 0xD3, 0x79,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const unsigned char xsC_tpki_cert[0x300] =
|
||||
{
|
||||
0x00, 0x01, 0x00, 0x04, 0x91, 0x9E, 0xBE, 0x46,
|
||||
0x4A, 0xD0, 0xF5, 0x52, 0xCD, 0x1B, 0x72, 0xE7,
|
||||
0x88, 0x49, 0x10, 0xCF, 0x55, 0xA9, 0xF0, 0x2E,
|
||||
0x50, 0x78, 0x96, 0x41, 0xD8, 0x96, 0x68, 0x3D,
|
||||
0xC0, 0x05, 0xBD, 0x0A, 0xEA, 0x87, 0x07, 0x9D,
|
||||
0x8A, 0xC2, 0x84, 0xC6, 0x75, 0x06, 0x5F, 0x74,
|
||||
0xC8, 0xBF, 0x37, 0xC8, 0x80, 0x44, 0x40, 0x95,
|
||||
0x02, 0xA0, 0x22, 0x98, 0x0B, 0xB8, 0xAD, 0x48,
|
||||
0x38, 0x3F, 0x6D, 0x28, 0xA7, 0x9D, 0xE3, 0x96,
|
||||
0x26, 0xCC, 0xB2, 0xB2, 0x2A, 0x0F, 0x19, 0xE4,
|
||||
0x10, 0x32, 0xF0, 0x94, 0xB3, 0x9F, 0xF0, 0x13,
|
||||
0x31, 0x46, 0xDE, 0xC8, 0xF6, 0xC1, 0xA9, 0xD5,
|
||||
0x5C, 0xD2, 0x8D, 0x9E, 0x1C, 0x47, 0xB3, 0xD1,
|
||||
0x1F, 0x4F, 0x54, 0x26, 0xC2, 0xC7, 0x80, 0x13,
|
||||
0x5A, 0x27, 0x75, 0xD3, 0xCA, 0x67, 0x9B, 0xC7,
|
||||
0xE8, 0x34, 0xF0, 0xE0, 0xFB, 0x58, 0xE6, 0x88,
|
||||
0x60, 0xA7, 0x13, 0x30, 0xFC, 0x95, 0x79, 0x17,
|
||||
0x93, 0xC8, 0xFB, 0xA9, 0x35, 0xA7, 0xA6, 0x90,
|
||||
0x8F, 0x22, 0x9D, 0xEE, 0x2A, 0x0C, 0xA6, 0xB9,
|
||||
0xB2, 0x3B, 0x12, 0xD4, 0x95, 0xA6, 0xFE, 0x19,
|
||||
0xD0, 0xD7, 0x26, 0x48, 0x21, 0x68, 0x78, 0x60,
|
||||
0x5A, 0x66, 0x53, 0x8D, 0xBF, 0x37, 0x68, 0x99,
|
||||
0x90, 0x5D, 0x34, 0x45, 0xFC, 0x5C, 0x72, 0x7A,
|
||||
0x0E, 0x13, 0xE0, 0xE2, 0xC8, 0x97, 0x1C, 0x9C,
|
||||
0xFA, 0x6C, 0x60, 0x67, 0x88, 0x75, 0x73, 0x2A,
|
||||
0x4E, 0x75, 0x52, 0x3D, 0x2F, 0x56, 0x2F, 0x12,
|
||||
0xAA, 0xBD, 0x15, 0x73, 0xBF, 0x06, 0xC9, 0x40,
|
||||
0x54, 0xAE, 0xFA, 0x81, 0xA7, 0x14, 0x17, 0xAF,
|
||||
0x9A, 0x4A, 0x06, 0x6D, 0x0F, 0xFC, 0x5A, 0xD6,
|
||||
0x4B, 0xAB, 0x28, 0xB1, 0xFF, 0x60, 0x66, 0x1F,
|
||||
0x44, 0x37, 0xD4, 0x9E, 0x1E, 0x0D, 0x94, 0x12,
|
||||
0xEB, 0x4B, 0xCA, 0xCF, 0x4C, 0xFD, 0x6A, 0x34,
|
||||
0x08, 0x84, 0x79, 0x82, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x43, 0x41, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x58, 0x53, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x63, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x13, 0x7A, 0x08, 0x94,
|
||||
0xAD, 0x50, 0x5B, 0xB6, 0xC6, 0x7E, 0x2E, 0x5B,
|
||||
0xDD, 0x6A, 0x3B, 0xEC, 0x43, 0xD9, 0x10, 0xC7,
|
||||
0x72, 0xE9, 0xCC, 0x29, 0x0D, 0xA5, 0x85, 0x88,
|
||||
0xB7, 0x7D, 0xCC, 0x11, 0x68, 0x0B, 0xB3, 0xE2,
|
||||
0x9F, 0x4E, 0xAB, 0xBB, 0x26, 0xE9, 0x8C, 0x26,
|
||||
0x01, 0x98, 0x5C, 0x04, 0x1B, 0xB1, 0x43, 0x78,
|
||||
0xE6, 0x89, 0x18, 0x1A, 0xAD, 0x77, 0x05, 0x68,
|
||||
0xE9, 0x28, 0xA2, 0xB9, 0x81, 0x67, 0xEE, 0x3E,
|
||||
0x10, 0xD0, 0x72, 0xBE, 0xEF, 0x1F, 0xA2, 0x2F,
|
||||
0xA2, 0xAA, 0x3E, 0x13, 0xF1, 0x1E, 0x18, 0x36,
|
||||
0xA9, 0x2A, 0x42, 0x81, 0xEF, 0x70, 0xAA, 0xF4,
|
||||
0xE4, 0x62, 0x99, 0x82, 0x21, 0xC6, 0xFB, 0xB9,
|
||||
0xBD, 0xD0, 0x17, 0xE6, 0xAC, 0x59, 0x04, 0x94,
|
||||
0xE9, 0xCE, 0xA9, 0x85, 0x9C, 0xEB, 0x2D, 0x2A,
|
||||
0x4C, 0x17, 0x66, 0xF2, 0xC3, 0x39, 0x12, 0xC5,
|
||||
0x8F, 0x14, 0xA8, 0x03, 0xE3, 0x6F, 0xCC, 0xDC,
|
||||
0xCC, 0xDC, 0x13, 0xFD, 0x7A, 0xE7, 0x7C, 0x7A,
|
||||
0x78, 0xD9, 0x97, 0xE6, 0xAC, 0xC3, 0x55, 0x57,
|
||||
0xE0, 0xD3, 0xE9, 0xEB, 0x64, 0xB4, 0x3C, 0x92,
|
||||
0xF4, 0xC5, 0x0D, 0x67, 0xA6, 0x02, 0xDE, 0xB3,
|
||||
0x91, 0xB0, 0x66, 0x61, 0xCD, 0x32, 0x88, 0x0B,
|
||||
0xD6, 0x49, 0x12, 0xAF, 0x1C, 0xBC, 0xB7, 0x16,
|
||||
0x2A, 0x06, 0xF0, 0x25, 0x65, 0xD3, 0xB0, 0xEC,
|
||||
0xE4, 0xFC, 0xEC, 0xDD, 0xAE, 0x8A, 0x49, 0x34,
|
||||
0xDB, 0x8E, 0xE6, 0x7F, 0x30, 0x17, 0x98, 0x62,
|
||||
0x21, 0x15, 0x5D, 0x13, 0x1C, 0x6C, 0x3F, 0x09,
|
||||
0xAB, 0x19, 0x45, 0xC2, 0x06, 0xAC, 0x70, 0xC9,
|
||||
0x42, 0xB3, 0x6F, 0x49, 0xA1, 0x18, 0x3B, 0xCD,
|
||||
0x78, 0xB6, 0xE4, 0xB4, 0x7C, 0x6C, 0x5C, 0xAC,
|
||||
0x0F, 0x8D, 0x62, 0xF8, 0x97, 0xC6, 0x95, 0x3D,
|
||||
0xD1, 0x2F, 0x28, 0xB7, 0x0C, 0x5B, 0x7D, 0xF7,
|
||||
0x51, 0x81, 0x9A, 0x98, 0x34, 0x65, 0x26, 0x25,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const unsigned char cpB_tpki_cert[0x300] =
|
||||
{
|
||||
0x00, 0x01, 0x00, 0x04, 0x2E, 0xA6, 0x6C, 0x66,
|
||||
0xCF, 0xF3, 0x35, 0x79, 0x7D, 0x04, 0x97, 0xB7,
|
||||
0x7A, 0x19, 0x7F, 0x9F, 0xE5, 0x1A, 0xB5, 0xA4,
|
||||
0x13, 0x75, 0xDC, 0x73, 0xFD, 0x9E, 0x0B, 0x10,
|
||||
0x66, 0x9B, 0x1B, 0x9A, 0x5B, 0x7E, 0x8A, 0xB2,
|
||||
0x8F, 0x01, 0xB6, 0x7B, 0x62, 0x54, 0xC1, 0x4A,
|
||||
0xA1, 0x33, 0x14, 0x18, 0xF2, 0x5B, 0xA5, 0x49,
|
||||
0x00, 0x4C, 0x37, 0x8D, 0xD7, 0x2F, 0x0C, 0xE6,
|
||||
0x3B, 0x1F, 0x70, 0x91, 0xAA, 0xFE, 0x38, 0x09,
|
||||
0xB7, 0xAC, 0x6C, 0x28, 0x76, 0xA6, 0x1D, 0x60,
|
||||
0x51, 0x6C, 0x43, 0xA6, 0x37, 0x29, 0x16, 0x2D,
|
||||
0x28, 0x0B, 0xE2, 0x1B, 0xE8, 0xE2, 0xFE, 0x05,
|
||||
0x7D, 0x8E, 0xB6, 0xE2, 0x04, 0x24, 0x22, 0x45,
|
||||
0x73, 0x1A, 0xB6, 0xFE, 0xE3, 0x0E, 0x53, 0x35,
|
||||
0x37, 0x3E, 0xEB, 0xA9, 0x70, 0xD5, 0x31, 0xBB,
|
||||
0xA2, 0xCB, 0x22, 0x2D, 0x96, 0x84, 0x38, 0x7D,
|
||||
0x5F, 0x2A, 0x1B, 0xF7, 0x52, 0x00, 0xCE, 0x06,
|
||||
0x56, 0xE3, 0x90, 0xCE, 0x19, 0x13, 0x5B, 0x59,
|
||||
0xE1, 0x4F, 0x0F, 0xA5, 0xC1, 0x28, 0x1A, 0x73,
|
||||
0x86, 0xCC, 0xD1, 0xC8, 0xEC, 0x3F, 0xAD, 0x70,
|
||||
0xFB, 0xCE, 0x74, 0xDE, 0xEE, 0x1F, 0xD0, 0x5F,
|
||||
0x46, 0x33, 0x0B, 0x51, 0xF9, 0xB7, 0x9E, 0x1D,
|
||||
0xDB, 0xF4, 0xE3, 0x3F, 0x14, 0x88, 0x9D, 0x05,
|
||||
0x28, 0x29, 0x24, 0xC5, 0xF5, 0xDC, 0x27, 0x66,
|
||||
0xEF, 0x06, 0x27, 0xD7, 0xEE, 0xDC, 0x73, 0x6E,
|
||||
0x67, 0xC2, 0xE5, 0xB9, 0x38, 0x34, 0x66, 0x80,
|
||||
0x72, 0x21, 0x6D, 0x1C, 0x78, 0xB8, 0x23, 0xA0,
|
||||
0x72, 0xD3, 0x4F, 0xF3, 0xEC, 0xF9, 0xBD, 0x11,
|
||||
0xA2, 0x9A, 0xF1, 0x6C, 0x33, 0xBD, 0x09, 0xAF,
|
||||
0xB2, 0xD7, 0x4D, 0x53, 0x4E, 0x02, 0x7C, 0x19,
|
||||
0x24, 0x0D, 0x59, 0x5A, 0x68, 0xEB, 0xB3, 0x05,
|
||||
0xAC, 0xC4, 0x4A, 0xB3, 0x8A, 0xB8, 0x20, 0xC6,
|
||||
0xD4, 0x26, 0x56, 0x0C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x43, 0x41, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x62, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x13, 0x7A, 0x08, 0x0B,
|
||||
0xA6, 0x89, 0xC5, 0x90, 0xFD, 0x0B, 0x2F, 0x0D,
|
||||
0x4F, 0x56, 0xB6, 0x32, 0xFB, 0x93, 0x4E, 0xD0,
|
||||
0x73, 0x95, 0x17, 0xB3, 0x3A, 0x79, 0xDE, 0x04,
|
||||
0x0E, 0xE9, 0x2D, 0xC3, 0x1D, 0x37, 0xC7, 0xF7,
|
||||
0x3B, 0xF0, 0x4B, 0xD3, 0xE4, 0x4E, 0x20, 0xAB,
|
||||
0x5A, 0x6F, 0xEA, 0xF5, 0x98, 0x4C, 0xC1, 0xF6,
|
||||
0x06, 0x2E, 0x9A, 0x9F, 0xE5, 0x6C, 0x32, 0x85,
|
||||
0xDC, 0x6F, 0x25, 0xDD, 0xD5, 0xD0, 0xBF, 0x9F,
|
||||
0xE2, 0xEF, 0xE8, 0x35, 0xDF, 0x26, 0x34, 0xED,
|
||||
0x93, 0x7F, 0xAB, 0x02, 0x14, 0xD1, 0x04, 0x80,
|
||||
0x9C, 0xF7, 0x4B, 0x86, 0x0E, 0x6B, 0x04, 0x83,
|
||||
0xF4, 0xCD, 0x2D, 0xAB, 0x2A, 0x96, 0x02, 0xBC,
|
||||
0x56, 0xF0, 0xD6, 0xBD, 0x94, 0x6A, 0xED, 0x6E,
|
||||
0x0B, 0xE4, 0xF0, 0x8F, 0x26, 0x68, 0x6B, 0xD0,
|
||||
0x9E, 0xF7, 0xDB, 0x32, 0x5F, 0x82, 0xB1, 0x8F,
|
||||
0x6A, 0xF2, 0xED, 0x52, 0x5B, 0xFD, 0x82, 0x8B,
|
||||
0x65, 0x3F, 0xEE, 0x6E, 0xCE, 0x40, 0x0D, 0x5A,
|
||||
0x48, 0xFF, 0xE2, 0x2D, 0x53, 0x8B, 0xB5, 0x33,
|
||||
0x5B, 0x41, 0x53, 0x34, 0x2D, 0x43, 0x35, 0xAC,
|
||||
0xF5, 0x90, 0xD0, 0xD3, 0x0A, 0xE2, 0x04, 0x3C,
|
||||
0x7F, 0x5A, 0xD2, 0x14, 0xFC, 0x9C, 0x0F, 0xE6,
|
||||
0xFA, 0x40, 0xA5, 0xC8, 0x65, 0x06, 0xCA, 0x63,
|
||||
0x69, 0xBC, 0xEE, 0x44, 0xA3, 0x2D, 0x9E, 0x69,
|
||||
0x5C, 0xF0, 0x0B, 0x4F, 0xD7, 0x9A, 0xDB, 0x56,
|
||||
0x8D, 0x14, 0x9C, 0x20, 0x28, 0xA1, 0x4C, 0x9D,
|
||||
0x71, 0xB8, 0x50, 0xCA, 0x36, 0x5B, 0x37, 0xF7,
|
||||
0x0B, 0x65, 0x77, 0x91, 0xFC, 0x5D, 0x72, 0x8C,
|
||||
0x4E, 0x18, 0xFD, 0x22, 0x55, 0x7C, 0x40, 0x62,
|
||||
0xD7, 0x47, 0x71, 0x53, 0x3C, 0x70, 0x17, 0x9D,
|
||||
0x3D, 0xAE, 0x8F, 0x92, 0xB1, 0x17, 0xE4, 0x5C,
|
||||
0xB3, 0x32, 0xF3, 0xB3, 0xC2, 0xA2, 0x2E, 0x70,
|
||||
0x5C, 0xFE, 0xC6, 0x6F, 0x6D, 0xA3, 0x77, 0x2B,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "lib.h"
|
||||
#include "ncch_build.h"
|
||||
#include "romfs.h"
|
||||
#include "romfs_gen.h"
|
||||
#include "romfs_import.h"
|
||||
|
||||
void FreeRomFsCtx(romfs_buildctx *ctx);
|
||||
|
||||
// RomFs Build Functions
|
||||
int SetupRomFs(ncch_settings *ncchset, romfs_buildctx *ctx)
|
||||
{
|
||||
ctx->verbose = ncchset->options.verbose;
|
||||
ctx->output = NULL;
|
||||
ctx->romfsSize = 0;
|
||||
|
||||
// If Not Using RomFS Return
|
||||
if(!ncchset->options.UseRomFS)
|
||||
return 0;
|
||||
|
||||
if(ncchset->componentFilePtrs.romfs)// The user has specified a pre-built RomFs Binary
|
||||
return PrepareImportRomFsBinaryFromFile(ncchset,ctx);
|
||||
|
||||
else // Otherwise build ROMFS
|
||||
return PrepareBuildRomFsBinary(ncchset,ctx);
|
||||
|
||||
}
|
||||
|
||||
int BuildRomFs(romfs_buildctx *ctx)
|
||||
{
|
||||
// If Not Using RomFS Return
|
||||
if(!ctx->romfsSize)
|
||||
return 0;
|
||||
|
||||
int result = 0;
|
||||
|
||||
if(ctx->ImportRomfsBinary) // The user has specified a pre-built RomFs Binary
|
||||
result = ImportRomFsBinaryFromFile(ctx);
|
||||
else // Otherwise build ROMFS
|
||||
result = BuildRomFsBinary(ctx);
|
||||
|
||||
FreeRomFsCtx(ctx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FreeRomFsCtx(romfs_buildctx *ctx)
|
||||
{
|
||||
if(ctx->fs){
|
||||
FreeDir(ctx->fs);
|
||||
free(ctx->fs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#pragma once
|
||||
#include "romfs_fs.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
INVALID_ROMFS_FILE = -10,
|
||||
} romfs_errors;
|
||||
|
||||
|
||||
// IVFC Structs
|
||||
typedef struct
|
||||
{
|
||||
u64 size;
|
||||
u64 offset;
|
||||
u64 logicalOffset;
|
||||
u8 *pos;
|
||||
u8 reserved[8];
|
||||
} ivfc_level;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 logicalOffset[8];
|
||||
u8 hashDataSize[8];
|
||||
u8 blockSize[4];
|
||||
u8 reserved[4];
|
||||
} ivfc_levelheader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 magic[4];
|
||||
u8 id[4];
|
||||
u8 masterHashSize[4];
|
||||
ivfc_levelheader level[3];
|
||||
u8 optionalSize[4];
|
||||
u8 reserved[4];
|
||||
} ivfc_hdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 offset[4];
|
||||
u8 size[4];
|
||||
} romfs_sectionheader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 headersize[4];
|
||||
romfs_sectionheader section[4]; // 8*4 = 0x20
|
||||
u8 dataoffset[4];
|
||||
} romfs_infoheader; //sizeof(romfs_infoheader) = 0x28
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 parentoffset[4];
|
||||
u8 siblingoffset[4];
|
||||
u8 childoffset[4];
|
||||
u8 fileoffset[4];
|
||||
u8 hashoffset[4];
|
||||
u8 namesize[4];
|
||||
//u8 name[ROMFS_MAXNAMESIZE];
|
||||
} romfs_direntry; //sizeof(romfs_direntry) = 0x18
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 parentdiroffset[4];
|
||||
u8 siblingoffset[4];
|
||||
u8 dataoffset[8];
|
||||
u8 datasize[8];
|
||||
u8 hashoffset[4];
|
||||
u8 namesize[4];
|
||||
//u8 name[ROMFS_MAXNAMESIZE];
|
||||
} romfs_fileentry; //sizeof(romfs_fileentry) = 0x20
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool verbose;
|
||||
|
||||
u8 *output;
|
||||
u64 romfsSize;
|
||||
u64 romfsHeaderSize;
|
||||
|
||||
/* For Importing ROMFS Binaries */
|
||||
bool ImportRomfsBinary;
|
||||
FILE *romfsBinary;
|
||||
|
||||
/* For Creating ROMFS Binaries */
|
||||
ivfc_hdr *ivfcHdr;
|
||||
romfs_infoheader *romfsHdr;
|
||||
|
||||
romfs_dir *fs;
|
||||
|
||||
u8 *dirHashTable;
|
||||
u32 m_dirHashTable;
|
||||
|
||||
u8 *dirTable;
|
||||
u32 dirNum;
|
||||
u32 m_dirTableLen;
|
||||
u32 u_dirTableLen;
|
||||
|
||||
u8 *fileHashTable;
|
||||
u32 m_fileHashTable;
|
||||
|
||||
u8 *fileTable;
|
||||
u32 fileNum;
|
||||
u32 m_fileTableLen;
|
||||
u32 u_fileTableLen;
|
||||
|
||||
u8 *data;
|
||||
u64 m_dataLen;
|
||||
u64 u_dataLen;
|
||||
|
||||
// Levels
|
||||
ivfc_level level[4];
|
||||
} romfs_buildctx;
|
||||
|
||||
int SetupRomFs(ncch_settings *ncchset, romfs_buildctx *ctx);
|
||||
int BuildRomFs(romfs_buildctx *ctx);
|
||||
@@ -0,0 +1,164 @@
|
||||
#include "lib.h"
|
||||
#include "romfs_fs.h"
|
||||
|
||||
/* This is the FS interface for ROMFS generation */
|
||||
/* Tested working on Windows/Linux/OSX */
|
||||
int PopulateDir(romfs_dir *dir);
|
||||
int InitDir(romfs_dir *dir);
|
||||
int ManageDir(romfs_dir *dir);
|
||||
|
||||
|
||||
int InitDir(romfs_dir *dir)
|
||||
{
|
||||
dir->m_child = 10;
|
||||
dir->u_child = 0;
|
||||
dir->child = calloc(dir->m_child,sizeof(romfs_dir));
|
||||
|
||||
dir->m_file = 10;
|
||||
dir->u_file = 0;
|
||||
dir->file = calloc(dir->m_file,sizeof(romfs_file));
|
||||
|
||||
if (dir->child == NULL || dir->file == NULL)
|
||||
return MEM_ERROR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ManageDir(romfs_dir *dir)
|
||||
{
|
||||
if (dir->u_child >= dir->m_child) {
|
||||
dir->m_child = 2 * dir->u_child;
|
||||
dir->child = realloc(dir->child, dir->m_child*sizeof(romfs_dir));
|
||||
}
|
||||
if (dir->u_file >= dir->m_file) {
|
||||
dir->m_file = 2 * dir->u_file;
|
||||
dir->file = realloc(dir->file, dir->m_file*sizeof(romfs_file));
|
||||
}
|
||||
|
||||
if (dir->child == NULL || dir->file == NULL)
|
||||
return MEM_ERROR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OpenRootDir(const char *path, romfs_dir *dir)
|
||||
{
|
||||
// Create native FS path
|
||||
dir->path = os_CopyConvertCharStr(path);
|
||||
// Copy romfs name (empty string)
|
||||
dir->name = utf16_CopyStr(ROMFS_EMPTY_PATH);
|
||||
dir->namesize = 0;
|
||||
|
||||
return PopulateDir(dir);
|
||||
}
|
||||
|
||||
int PopulateDir(romfs_dir *dir)
|
||||
{
|
||||
_OSDIR *dp, *tmp_dp;
|
||||
struct _osdirent *entry;
|
||||
|
||||
if (InitDir(dir))
|
||||
return MEM_ERROR;
|
||||
|
||||
// Open Directory
|
||||
if((dp = os_opendir(dir->path)) == NULL)
|
||||
{
|
||||
printf("[ROMFS] Failed to open directory: \"");
|
||||
os_fputs(dir->path, stdout);
|
||||
printf("\"\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Process Entries
|
||||
while ((entry = os_readdir(dp)) != NULL)
|
||||
{
|
||||
// Skip if "." or ".."
|
||||
if (os_strcmp(entry->d_name, OS_CURRENT_DIR_PATH) == 0 || os_strcmp(entry->d_name, OS_PARENT_DIR_PATH) == 0)
|
||||
continue;
|
||||
|
||||
// Ensures that there is always memory for child directory and file structs
|
||||
if (ManageDir(dir))
|
||||
return MEM_ERROR;
|
||||
|
||||
// Get native FS path
|
||||
oschar_t *path = os_AppendToPath(dir->path, entry->d_name);
|
||||
|
||||
// Opening directory with fs path to test if directory
|
||||
if ((tmp_dp = os_opendir(path)) != NULL) {
|
||||
os_closedir(tmp_dp);
|
||||
|
||||
dir->child[dir->u_child].path = path;
|
||||
dir->child[dir->u_child].name = utf16_CopyConvertOsStr(entry->d_name);
|
||||
dir->child[dir->u_child].namesize = os_strlen(entry->d_name)*sizeof(utf16char_t);
|
||||
dir->u_child++;
|
||||
|
||||
// Populate directory
|
||||
PopulateDir(&dir->child[dir->u_child-1]);
|
||||
}
|
||||
// Otherwise this is a file
|
||||
else {
|
||||
dir->file[dir->u_file].path = path;
|
||||
dir->file[dir->u_file].name = utf16_CopyConvertOsStr(entry->d_name);
|
||||
dir->file[dir->u_file].namesize = os_strlen(entry->d_name)*sizeof(utf16char_t);
|
||||
dir->file[dir->u_file].size = os_fsize(path);
|
||||
dir->u_file++;
|
||||
}
|
||||
}
|
||||
|
||||
os_closedir(dp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PrintDir(romfs_dir *dir, u32 depth)
|
||||
{
|
||||
for(u32 i = 0; i < depth; i++)
|
||||
printf(" ");
|
||||
|
||||
if (depth > 0)
|
||||
utf16_fputs(dir->name, stdout);
|
||||
else
|
||||
printf("romfs:");
|
||||
putchar('\n');
|
||||
|
||||
if(dir->u_file)
|
||||
{
|
||||
for(u32 i = 0; i < dir->u_file; i++)
|
||||
{
|
||||
for(u32 j = 0; j < depth+1; j++)
|
||||
printf(" ");
|
||||
utf16_fputs(dir->file[i].name, stdout);
|
||||
printf(" (0x%"PRIx64")\n", dir->file[i].size);
|
||||
}
|
||||
}
|
||||
if(dir->u_child)
|
||||
{
|
||||
for(u32 i = 0; i < dir->u_child; i++)
|
||||
PrintDir(&dir->child[i],depth+1);
|
||||
}
|
||||
}
|
||||
|
||||
void FreeDir(romfs_dir *dir)
|
||||
{
|
||||
//printf("DIR!! free file names\n");
|
||||
for(u32 i = 0; i < dir->u_file; i++)
|
||||
{
|
||||
free(dir->file[i].path);
|
||||
free(dir->file[i].name);
|
||||
}
|
||||
//printf("free file struct\n");
|
||||
free(dir->file);
|
||||
|
||||
|
||||
//printf("free dir names and\n");
|
||||
for(u32 i = 0; i < dir->u_child; i++)
|
||||
{
|
||||
free(dir->child[i].path);
|
||||
free(dir->child[i].name);
|
||||
FreeDir(&dir->child[i]);
|
||||
}
|
||||
//printf("free dir struct\n");
|
||||
free(dir->child);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include "oschar.h"
|
||||
|
||||
struct romfs_file
|
||||
{
|
||||
oschar_t *path;
|
||||
utf16char_t *name;
|
||||
u32 namesize;
|
||||
u64 size;
|
||||
};
|
||||
|
||||
struct romfs_dir
|
||||
{
|
||||
oschar_t *path;
|
||||
utf16char_t *name;
|
||||
u32 namesize;
|
||||
|
||||
struct romfs_dir *child;
|
||||
u32 m_child;
|
||||
u32 u_child;
|
||||
|
||||
struct romfs_file *file;
|
||||
u32 m_file;
|
||||
u32 u_file;
|
||||
};
|
||||
|
||||
typedef struct romfs_file romfs_file;
|
||||
typedef struct romfs_dir romfs_dir;
|
||||
|
||||
static const utf16char_t ROMFS_EMPTY_PATH[2] = { 0 };
|
||||
static const oschar_t OS_EMPTY_PATH[2] = { 0 };
|
||||
static const oschar_t OS_CURRENT_DIR_PATH[2] = { '.' };
|
||||
static const oschar_t OS_PARENT_DIR_PATH[3] = { '.', '.' };
|
||||
|
||||
int OpenRootDir(const char *path, romfs_dir *dir);
|
||||
void PrintDir(romfs_dir *dir, u32 depth);
|
||||
void FreeDir(romfs_dir *dir);
|
||||
@@ -0,0 +1,475 @@
|
||||
#include "lib.h"
|
||||
#include "ncch_build.h"
|
||||
#include "romfs.h"
|
||||
|
||||
const int ROMFS_BLOCK_SIZE = 0x1000;
|
||||
const unsigned int ROMFS_UNUSED_ENTRY = 0xffffffff;
|
||||
|
||||
// Build
|
||||
bool IsFileWanted(romfs_file *file, void *filter_criteria);
|
||||
bool IsDirWanted(romfs_dir *dir, void *filter_criteria);
|
||||
void CalcDirSize(romfs_buildctx *ctx, romfs_dir *fs);
|
||||
void CalcRomfsSize(romfs_buildctx *ctx);
|
||||
int FilterRomFS(romfs_dir *fs_raw, romfs_dir *fs_filtered, void *filter_criteria);
|
||||
void AddFileToRomfs(romfs_buildctx *ctx, romfs_file *file, u32 parent, u32 sibling);
|
||||
void AddDirToRomfs(romfs_buildctx *ctx, romfs_dir *fs, u32 parent, u32 sibling);
|
||||
void AddDirChildrenToRomfs(romfs_buildctx *ctx, romfs_dir *fs, u32 parent, u32 dir);
|
||||
void PopulateHashTable(romfs_buildctx *ctx);
|
||||
void PopulateRomfs(romfs_buildctx *ctx);
|
||||
void BuildRomfsHeader(romfs_buildctx *ctx);
|
||||
void BuildIvfcHeader(romfs_buildctx *ctx);
|
||||
void GenIvfcHashTree(romfs_buildctx *ctx);
|
||||
u32 CalcPathHash(u32 parent, const utf16char_t* path);
|
||||
|
||||
|
||||
int PrepareBuildRomFsBinary(ncch_settings *ncchset, romfs_buildctx *ctx)
|
||||
{
|
||||
/* FS Structures */
|
||||
void *filter_criteria = NULL;
|
||||
romfs_dir *fs_raw = calloc(1,sizeof(romfs_dir));
|
||||
ctx->fs = calloc(1,sizeof(romfs_dir));
|
||||
|
||||
/* Import FS and process */
|
||||
OpenRootDir(ncchset->rsfSet->RomFs.RootPath,fs_raw);
|
||||
FilterRomFS(fs_raw,ctx->fs,filter_criteria);
|
||||
|
||||
/* free unfiltered FS */
|
||||
FreeDir(fs_raw);
|
||||
free(fs_raw);
|
||||
|
||||
/* Abort romfs making, if no wanted files/directories were found */
|
||||
if(ctx->fs->u_file == 0 && ctx->fs->u_child == 0){
|
||||
ctx->romfsSize = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CalcRomfsSize(ctx);
|
||||
|
||||
if (ctx->verbose) {
|
||||
printf("[ROMFS] File System:\n");
|
||||
printf(" > Size: %"PRIx64"\n", ctx->romfsSize);
|
||||
printf(" > Directories: %d\n", ctx->dirNum);
|
||||
printf(" > Files: %d\n", ctx->fileNum);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BuildRomFsBinary(romfs_buildctx *ctx)
|
||||
{
|
||||
/* Decide IVFC Level Actual Offsets */
|
||||
ctx->level[0].offset = 0;
|
||||
ctx->level[3].offset = ctx->level[0].offset + align(ctx->level[0].size, ROMFS_BLOCK_SIZE);
|
||||
ctx->level[1].offset = ctx->level[3].offset + align(ctx->level[3].size, ROMFS_BLOCK_SIZE);
|
||||
ctx->level[2].offset = ctx->level[1].offset + align(ctx->level[1].size, ROMFS_BLOCK_SIZE);
|
||||
|
||||
/* Decide IVFC Level Logical Offsets */
|
||||
for(int i = 1; i < 4; i++){
|
||||
if(i == 1)
|
||||
ctx->level[i].logicalOffset = 0;
|
||||
else
|
||||
ctx->level[i].logicalOffset = align(ctx->level[i-1].logicalOffset + ctx->level[i-1].size,ROMFS_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/* Setup IVFC Level Ptrs */
|
||||
for(int i = 0; i < 4; i++){
|
||||
ctx->level[i].pos = (ctx->output + ctx->level[i].offset);
|
||||
if(i == 0)
|
||||
ctx->level[i].pos += align(sizeof(ivfc_hdr),0x10);
|
||||
}
|
||||
|
||||
/* Build Romfs */
|
||||
ctx->romfsHdr = (romfs_infoheader*)(ctx->level[3].pos);
|
||||
BuildRomfsHeader(ctx);
|
||||
PopulateRomfs(ctx);
|
||||
|
||||
|
||||
/* Finalise by building IVFC hash tree */
|
||||
ctx->ivfcHdr = (ivfc_hdr*)(ctx->output + ctx->level[0].offset);
|
||||
BuildIvfcHeader(ctx);
|
||||
GenIvfcHashTree(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool IsFileWanted(romfs_file *file, void *filter_criteria)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsDirWanted(romfs_dir *dir, void *filter_criteria)
|
||||
{
|
||||
bool ret = false;
|
||||
for(u32 i = 0; i < dir->u_file; i++)
|
||||
{
|
||||
if(IsFileWanted(&dir->file[i],filter_criteria))
|
||||
{
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(u32 i = 0; i < dir->u_child; i++)
|
||||
{
|
||||
if(IsDirWanted(&dir->child[i],filter_criteria))
|
||||
{
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CalcDirSize(romfs_buildctx *ctx, romfs_dir *fs)
|
||||
{
|
||||
if(ctx->m_dirTableLen == 0)
|
||||
ctx->m_dirTableLen = sizeof(romfs_direntry);
|
||||
else
|
||||
ctx->m_dirTableLen += sizeof(romfs_direntry) + align(fs->namesize,4);
|
||||
|
||||
for(u32 i = 0; i < fs->u_file; i++)
|
||||
{
|
||||
ctx->m_fileTableLen += sizeof(romfs_fileentry) + align(fs->file[i].namesize,4);
|
||||
if(fs->file[i].size)
|
||||
ctx->m_dataLen = align(ctx->m_dataLen,0x10) + fs->file[i].size;
|
||||
}
|
||||
|
||||
for(u32 i = 0; i < fs->u_child; i++)
|
||||
{
|
||||
CalcDirSize(ctx,&fs->child[i]);
|
||||
}
|
||||
ctx->fileNum += fs->u_file;
|
||||
ctx->dirNum += fs->u_child;
|
||||
}
|
||||
|
||||
u32 GetHashTableCount(u32 num)
|
||||
{
|
||||
u32 count = num;
|
||||
if (num < 3)
|
||||
count = 3;
|
||||
else if (count < 19)
|
||||
count |= 1;
|
||||
else {
|
||||
while (count % 2 == 0 || count % 3 == 0 || count % 5 == 0 || count % 7 == 0 || count % 11 == 0 || count % 13 == 0 || count % 17 == 0)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void CalcRomfsSize(romfs_buildctx *ctx)
|
||||
{
|
||||
ctx->dirNum = 1; // root dir
|
||||
CalcDirSize(ctx,ctx->fs);
|
||||
|
||||
ctx->m_dirHashTable = GetHashTableCount(ctx->dirNum);
|
||||
|
||||
ctx->m_fileHashTable = GetHashTableCount(ctx->fileNum);
|
||||
|
||||
u32 romfsHdrSize = align(sizeof(romfs_infoheader) + ctx->m_dirHashTable*sizeof(u32) + ctx->m_dirTableLen + ctx->m_fileHashTable*sizeof(u32) + ctx->m_fileTableLen,0x10);
|
||||
|
||||
ctx->level[3].size = romfsHdrSize + ctx->m_dataLen; // data
|
||||
ctx->level[2].size = align(ctx->level[3].size,ROMFS_BLOCK_SIZE) / ROMFS_BLOCK_SIZE * SHA_256_LEN ;
|
||||
ctx->level[1].size = align(ctx->level[2].size,ROMFS_BLOCK_SIZE) / ROMFS_BLOCK_SIZE * SHA_256_LEN ;
|
||||
ctx->level[0].size = align(ctx->level[1].size,ROMFS_BLOCK_SIZE) / ROMFS_BLOCK_SIZE * SHA_256_LEN + align(sizeof(ivfc_hdr),0x10); // hdr
|
||||
|
||||
ctx->romfsHeaderSize = ctx->level[0].size;
|
||||
|
||||
ctx->romfsSize = 0;
|
||||
for(int i = 0; i < 4; i++)
|
||||
ctx->romfsSize += align(ctx->level[i].size,ROMFS_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
int FilterRomFS(romfs_dir *fs_raw, romfs_dir *fs_filtered, void *filter_criteria)
|
||||
{
|
||||
memset(fs_filtered,0,sizeof(romfs_dir));
|
||||
if(!IsDirWanted(fs_raw,filter_criteria))
|
||||
return 0;
|
||||
|
||||
fs_filtered->path = os_CopyStr(fs_raw->path);
|
||||
|
||||
fs_filtered->namesize = fs_raw->namesize;
|
||||
fs_filtered->name = utf16_CopyStr(fs_raw->name);
|
||||
|
||||
fs_filtered->u_child = 0;
|
||||
fs_filtered->m_child = fs_raw->u_child;
|
||||
fs_filtered->child = calloc(fs_filtered->m_child,sizeof(romfs_dir));
|
||||
|
||||
fs_filtered->u_file = 0;
|
||||
fs_filtered->m_file = fs_raw->u_file;
|
||||
fs_filtered->file = calloc(fs_filtered->m_file,sizeof(romfs_file));
|
||||
|
||||
for(u32 i = 0; i < fs_raw->u_child; i++)
|
||||
{
|
||||
if(IsDirWanted(&fs_raw->child[i],filter_criteria))
|
||||
{
|
||||
FilterRomFS(&fs_raw->child[i],&fs_filtered->child[fs_filtered->u_child],filter_criteria);
|
||||
fs_filtered->u_child++;
|
||||
}
|
||||
}
|
||||
|
||||
for(u32 i = 0; i < fs_raw->u_file; i++)
|
||||
{
|
||||
if(IsFileWanted(&fs_raw->file[i],filter_criteria))
|
||||
{
|
||||
fs_filtered->file[fs_filtered->u_file].path = os_CopyStr(fs_raw->file[i].path);
|
||||
|
||||
fs_filtered->file[fs_filtered->u_file].namesize = fs_raw->file[i].namesize;
|
||||
fs_filtered->file[fs_filtered->u_file].name = utf16_CopyStr(fs_raw->file[i].name);
|
||||
|
||||
fs_filtered->file[fs_filtered->u_file].size = fs_raw->file[i].size;
|
||||
|
||||
fs_filtered->u_file++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BuildRomfsHeader(romfs_buildctx *ctx)
|
||||
{
|
||||
u32 level3_pos = 0;
|
||||
|
||||
u32_to_u8(ctx->romfsHdr->headersize,sizeof(romfs_infoheader),LE);
|
||||
|
||||
level3_pos += sizeof(romfs_infoheader);
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
if(i == 0){
|
||||
ctx->dirHashTable = ctx->level[3].pos + level3_pos;
|
||||
u32_to_u8(ctx->romfsHdr->section[i].offset,level3_pos,LE);
|
||||
u32_to_u8(ctx->romfsHdr->section[i].size,ctx->m_dirHashTable*sizeof(u32),LE);
|
||||
level3_pos += ctx->m_dirHashTable*sizeof(u32);
|
||||
}
|
||||
else if(i == 1 && ctx->m_dirTableLen){
|
||||
ctx->dirTable = ctx->level[3].pos + level3_pos;
|
||||
u32_to_u8(ctx->romfsHdr->section[i].offset,level3_pos,LE);
|
||||
u32_to_u8(ctx->romfsHdr->section[i].size,ctx->m_dirTableLen,LE);
|
||||
level3_pos += ctx->m_dirTableLen;
|
||||
}
|
||||
else if(i == 2){
|
||||
ctx->fileHashTable = ctx->level[3].pos + level3_pos;
|
||||
u32_to_u8(ctx->romfsHdr->section[i].offset,level3_pos,LE);
|
||||
u32_to_u8(ctx->romfsHdr->section[i].size,ctx->m_fileHashTable*sizeof(u32),LE);
|
||||
level3_pos += ctx->m_fileHashTable*sizeof(u32);
|
||||
}
|
||||
else if(i == 3 && ctx->m_fileTableLen){
|
||||
ctx->fileTable = ctx->level[3].pos + level3_pos;
|
||||
u32_to_u8(ctx->romfsHdr->section[i].offset,level3_pos,LE);
|
||||
u32_to_u8(ctx->romfsHdr->section[i].size,ctx->m_fileTableLen,LE);
|
||||
level3_pos += ctx->m_fileTableLen;
|
||||
}
|
||||
else{
|
||||
u32_to_u8(ctx->romfsHdr->section[i].offset,0,LE);
|
||||
u32_to_u8(ctx->romfsHdr->section[i].size,0,LE);
|
||||
}
|
||||
}
|
||||
|
||||
ctx->data = ctx->level[3].pos + align(level3_pos,0x10);
|
||||
u32_to_u8(ctx->romfsHdr->dataoffset,align(level3_pos,0x10),LE);
|
||||
|
||||
for (u32 i = 0; i < ctx->m_dirHashTable; i++) {
|
||||
u32_to_u8(ctx->dirHashTable+i*4, ROMFS_UNUSED_ENTRY, LE);
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < ctx->m_fileHashTable; i++) {
|
||||
u32_to_u8(ctx->fileHashTable+i*4, ROMFS_UNUSED_ENTRY, LE);
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetFileHashTableIndex(romfs_buildctx *ctx, u32 parent, const utf16char_t *path)
|
||||
{
|
||||
u32 hash = CalcPathHash(parent, path);
|
||||
return hash % ctx->m_fileHashTable;
|
||||
}
|
||||
|
||||
u32 GetDirHashTableIndex(romfs_buildctx *ctx, u32 parent, const utf16char_t* path)
|
||||
{
|
||||
u32 hash = CalcPathHash(parent, path);
|
||||
return hash % ctx->m_dirHashTable;
|
||||
}
|
||||
|
||||
void AddFileToRomfs(romfs_buildctx *ctx, romfs_file *file, u32 parent, u32 sibling)
|
||||
{
|
||||
romfs_fileentry *entry = (romfs_fileentry*)(ctx->fileTable + ctx->u_fileTableLen);
|
||||
|
||||
u32_to_u8(entry->parentdiroffset,parent,LE);
|
||||
u32_to_u8(entry->siblingoffset,sibling,LE);
|
||||
|
||||
/* Import name */
|
||||
u32_to_u8(entry->namesize,file->namesize,LE);
|
||||
u8 *name_pos = (u8*)(ctx->fileTable + ctx->u_fileTableLen + sizeof(romfs_fileentry));
|
||||
memset(name_pos,0,align(file->namesize,4));
|
||||
memcpy(name_pos,(u8*)file->name,file->namesize);
|
||||
|
||||
/* Set hash data */
|
||||
u32 hashindex = GetFileHashTableIndex(ctx, parent, file->name);
|
||||
u32_to_u8(entry->hashoffset, u8_to_u32(ctx->fileHashTable + hashindex*4, LE), LE);
|
||||
u32_to_u8(ctx->fileHashTable + hashindex*4, ctx->u_fileTableLen, LE);
|
||||
|
||||
/* Import data */
|
||||
if(file->size)
|
||||
{
|
||||
ctx->u_dataLen = align(ctx->u_dataLen,0x10); // Padding
|
||||
u64_to_u8(entry->dataoffset,ctx->u_dataLen,LE);
|
||||
u64_to_u8(entry->datasize,file->size,LE);
|
||||
u8 *data_pos = (ctx->data + ctx->u_dataLen);
|
||||
|
||||
if (ctx->verbose) {
|
||||
printf("[ROMFS] Reading \"");
|
||||
os_fputs(file->path, stdout);
|
||||
printf("\"... ");
|
||||
}
|
||||
|
||||
FILE *fp = os_fopen(file->path, OS_MODE_READ);
|
||||
fread(data_pos, file->size, 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
if (ctx->verbose) {
|
||||
printf("Done!\n");
|
||||
}
|
||||
|
||||
ctx->u_dataLen += file->size; // adding file size
|
||||
}
|
||||
else
|
||||
u64_to_u8(entry->dataoffset,0x00,LE);
|
||||
|
||||
/* Increment used file table length */
|
||||
ctx->u_fileTableLen += sizeof(romfs_fileentry) + align(file->namesize,4);
|
||||
}
|
||||
|
||||
void AddDirToRomfs(romfs_buildctx *ctx, romfs_dir *fs, u32 parent, u32 sibling)
|
||||
{
|
||||
u32 offset = ctx->u_dirTableLen;
|
||||
romfs_direntry *entry = (romfs_direntry*)(ctx->dirTable + offset);
|
||||
|
||||
/* Set entry data */
|
||||
u32_to_u8(entry->parentoffset,parent,LE);
|
||||
u32_to_u8(entry->siblingoffset,sibling,LE);
|
||||
u32_to_u8(entry->childoffset, ROMFS_UNUSED_ENTRY, LE);
|
||||
u32_to_u8(entry->fileoffset, ROMFS_UNUSED_ENTRY, LE);
|
||||
|
||||
/* Import name */
|
||||
u32_to_u8(entry->namesize,fs->namesize,LE);
|
||||
u8 *name_pos = (u8*)(ctx->dirTable + ctx->u_dirTableLen + sizeof(romfs_direntry));
|
||||
memset(name_pos,0,(u32)align(fs->namesize,4));
|
||||
memcpy(name_pos,(u8*)fs->name,fs->namesize);
|
||||
|
||||
/* Set hash data */
|
||||
u32 hashindex = GetDirHashTableIndex(ctx, parent, fs->name);
|
||||
u32_to_u8(entry->hashoffset, u8_to_u32(ctx->dirHashTable + hashindex * 4, LE), LE);
|
||||
u32_to_u8(ctx->dirHashTable + hashindex * 4, offset, LE);
|
||||
|
||||
/* Increment used dir table length */
|
||||
ctx->u_dirTableLen += sizeof(romfs_direntry) + (u32)align(fs->namesize,4);
|
||||
}
|
||||
|
||||
void AddDirChildrenToRomfs(romfs_buildctx *ctx, romfs_dir *fs, u32 parent, u32 dir)
|
||||
{
|
||||
romfs_direntry *entry = (romfs_direntry*)(ctx->dirTable + dir);
|
||||
|
||||
if (fs->u_file)
|
||||
{
|
||||
u32_to_u8(entry->fileoffset, ctx->u_fileTableLen, LE);
|
||||
|
||||
/* Create file entries*/
|
||||
for (u32 i = 0; i < fs->u_file; i++)
|
||||
{
|
||||
/* If is the last file, no more siblings */
|
||||
u32 file_sibling = 0;
|
||||
if (i >= fs->u_file - 1)
|
||||
file_sibling = ROMFS_UNUSED_ENTRY;
|
||||
else
|
||||
file_sibling = ctx->u_fileTableLen + sizeof(romfs_fileentry) + (u32)align(fs->file[i].namesize, 4);
|
||||
|
||||
/* Create file entry */
|
||||
AddFileToRomfs(ctx, &fs->file[i], dir, file_sibling);
|
||||
}
|
||||
}
|
||||
|
||||
if (fs->u_child)
|
||||
{
|
||||
/* Prepare to store child addresses */
|
||||
u32 *childs = calloc(fs->u_child, sizeof(u32));
|
||||
|
||||
/* Create child directory entries*/
|
||||
u32_to_u8(entry->childoffset, ctx->u_dirTableLen, LE);
|
||||
for (u32 i = 0; i < fs->u_child; i++)
|
||||
{
|
||||
/* Store address for child */
|
||||
childs[i] = ctx->u_dirTableLen;
|
||||
|
||||
/* If is the last child directory, no more siblings */
|
||||
u32 dir_sibling = 0;
|
||||
if (i >= fs->u_child - 1)
|
||||
dir_sibling = ROMFS_UNUSED_ENTRY;
|
||||
else
|
||||
dir_sibling = ctx->u_dirTableLen + sizeof(romfs_direntry) + (u32)align(fs->child[i].namesize, 4);
|
||||
|
||||
/* Create child directory entry */
|
||||
AddDirToRomfs(ctx, &fs->child[i], dir, dir_sibling);
|
||||
}
|
||||
|
||||
/* Populate child's childs */
|
||||
for (u32 i = 0; i < fs->u_child; i++)
|
||||
{
|
||||
AddDirChildrenToRomfs(ctx, &fs->child[i], dir, childs[i]);
|
||||
}
|
||||
|
||||
free(childs);
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateRomfs(romfs_buildctx *ctx)
|
||||
{
|
||||
AddDirToRomfs(ctx, ctx->fs, 0x0, ROMFS_UNUSED_ENTRY);
|
||||
AddDirChildrenToRomfs(ctx, ctx->fs, 0x0, 0);
|
||||
}
|
||||
|
||||
void BuildIvfcHeader(romfs_buildctx *ctx)
|
||||
{
|
||||
memcpy(ctx->ivfcHdr->magic,"IVFC",4);
|
||||
u32_to_u8(ctx->ivfcHdr->id,0x10000,LE);
|
||||
|
||||
u32 masterHashSize = ( align(ctx->level[1].size,ROMFS_BLOCK_SIZE) / ROMFS_BLOCK_SIZE ) * SHA_256_LEN ;
|
||||
u32_to_u8(ctx->ivfcHdr->masterHashSize,masterHashSize,LE);
|
||||
|
||||
for(int i = 1; i < 4; i++){
|
||||
u64_to_u8(ctx->ivfcHdr->level[i-1].logicalOffset,ctx->level[i].logicalOffset,LE);
|
||||
u64_to_u8(ctx->ivfcHdr->level[i-1].hashDataSize,ctx->level[i].size,LE);
|
||||
u32_to_u8(ctx->ivfcHdr->level[i-1].blockSize,log2l(ROMFS_BLOCK_SIZE),LE);
|
||||
}
|
||||
|
||||
u32_to_u8(ctx->ivfcHdr->optionalSize,sizeof(ivfc_hdr),LE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GenIvfcHashTree(romfs_buildctx *ctx)
|
||||
{
|
||||
for(int i = 2; i >= 0; i--){
|
||||
if (ctx->verbose)
|
||||
printf("[ROMFS] Generating IVFC level %d hashes... ", i+1);
|
||||
u32 numHashes = align(ctx->level[i+1].size,ROMFS_BLOCK_SIZE) / ROMFS_BLOCK_SIZE;
|
||||
for(u32 j = 0; j < numHashes; j++){
|
||||
u8 *datapos = (u8*)(ctx->level[i+1].pos + ROMFS_BLOCK_SIZE * j);
|
||||
u8 *hashpos = (u8*)(ctx->level[i].pos + SHA_256_LEN * j);
|
||||
ShaCalc(datapos, ROMFS_BLOCK_SIZE, hashpos, CTR_SHA_256);
|
||||
}
|
||||
if (ctx->verbose)
|
||||
printf("Done!\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
u32 CalcPathHash(u32 parent, const utf16char_t* path)
|
||||
{
|
||||
u32 len = utf16_strlen(path);
|
||||
u32 hash = parent ^ 123456789;
|
||||
for( u32 i = 0; i < len; i++ )
|
||||
{
|
||||
hash = (u32)((hash >> 5) | (hash << 27));//ror
|
||||
hash ^= (u16)path[i];
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "romfs.h"
|
||||
|
||||
int PrepareBuildRomFsBinary(ncch_settings *ncchset, romfs_buildctx *ctx);
|
||||
int BuildRomFsBinary(romfs_buildctx *ctx);
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "lib.h"
|
||||
#include "romfs_fs.h"
|
||||
#include "ncch_build.h"
|
||||
#include "romfs.h"
|
||||
|
||||
int PrepareImportRomFsBinaryFromFile(ncch_settings *ncchset, romfs_buildctx *ctx)
|
||||
{
|
||||
ctx->ImportRomfsBinary = true;
|
||||
ctx->romfsSize = ncchset->componentFilePtrs.romfsSize;
|
||||
ctx->romfsBinary = ncchset->componentFilePtrs.romfs;
|
||||
|
||||
ivfc_hdr *hdr = calloc(1,sizeof(ivfc_hdr));
|
||||
|
||||
ReadFile64(hdr,sizeof(ivfc_hdr),0,ctx->romfsBinary);
|
||||
if(memcmp(hdr->magic,"IVFC",4) != 0){
|
||||
fprintf(stderr,"[ROMFS ERROR] Invalid RomFS Binary.\n");
|
||||
return INVALID_ROMFS_FILE;
|
||||
}
|
||||
|
||||
ctx->romfsHeaderSize = align(sizeof(ivfc_hdr),0x10) + (u64)u8_to_u32(hdr->masterHashSize,LE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ImportRomFsBinaryFromFile(romfs_buildctx *ctx)
|
||||
{
|
||||
ReadFile64(ctx->output,ctx->romfsSize,0,ctx->romfsBinary);
|
||||
if(memcmp(ctx->output,"IVFC",4) != 0){
|
||||
fprintf(stderr,"[ROMFS ERROR] Invalid RomFS Binary.\n");
|
||||
return INVALID_ROMFS_FILE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
int PrepareImportRomFsBinaryFromFile(ncch_settings *ncchset, romfs_buildctx *ctx);
|
||||
int ImportRomFsBinaryFromFile(romfs_buildctx *ctx);
|
||||
@@ -0,0 +1,486 @@
|
||||
#include "lib.h"
|
||||
|
||||
void GET_Option(ctr_yaml_context *ctx, rsf_settings *rsf);
|
||||
void GET_AccessControlInfo(ctr_yaml_context *ctx, rsf_settings *rsf);
|
||||
void GET_SystemControlInfo(ctr_yaml_context *ctx, rsf_settings *rsf);
|
||||
void GET_BasicInfo(ctr_yaml_context *ctx, rsf_settings *rsf);
|
||||
void GET_RomFs(ctr_yaml_context *ctx, rsf_settings *rsf);
|
||||
void GET_TitleInfo(ctr_yaml_context *ctx, rsf_settings *rsf);
|
||||
void GET_CardInfo(ctr_yaml_context *ctx, rsf_settings *rsf);
|
||||
void GET_CommonHeaderKey(ctr_yaml_context *ctx, rsf_settings *rsf);
|
||||
|
||||
void EvaluateRSF(rsf_settings *rsf, ctr_yaml_context *ctx)
|
||||
{
|
||||
u32 start_level = ctx->Level-1;
|
||||
|
||||
/* Check Group Key for Validity */
|
||||
CHECK_Group:
|
||||
//printf("RSF Found: %s\n",GetYamlString(ctx));
|
||||
if(cmpYamlValue("Option",ctx)) {FinishEvent(ctx); GET_Option(ctx,rsf); goto GET_NextGroup;}
|
||||
else if(cmpYamlValue("AccessControlInfo",ctx)) {FinishEvent(ctx); GET_AccessControlInfo(ctx,rsf); goto GET_NextGroup;}
|
||||
else if(cmpYamlValue("SystemControlInfo",ctx)) {FinishEvent(ctx); GET_SystemControlInfo(ctx,rsf); goto GET_NextGroup;}
|
||||
else if(cmpYamlValue("BasicInfo",ctx)) {FinishEvent(ctx); GET_BasicInfo(ctx,rsf); goto GET_NextGroup;}
|
||||
else if(cmpYamlValue("RomFs",ctx)) {FinishEvent(ctx); GET_RomFs(ctx,rsf); goto GET_NextGroup;}
|
||||
else if(cmpYamlValue("TitleInfo",ctx)) {FinishEvent(ctx); GET_TitleInfo(ctx,rsf); goto GET_NextGroup;}
|
||||
else if(cmpYamlValue("CardInfo",ctx)) {FinishEvent(ctx); GET_CardInfo(ctx,rsf); goto GET_NextGroup;}
|
||||
else if(cmpYamlValue("CommonHeaderKey",ctx)) {FinishEvent(ctx); GET_CommonHeaderKey(ctx,rsf); goto GET_NextGroup;}
|
||||
|
||||
// If not recognised escape:
|
||||
fprintf(stderr,"[RSF ERROR] Unrecognised Key: '%s'\n",GetYamlString(ctx));
|
||||
FinishEvent(ctx);
|
||||
ctx->error = YAML_BAD_GROUP_HEADER;
|
||||
return;
|
||||
|
||||
/* Get Next Group and call check */
|
||||
GET_NextGroup:
|
||||
// If done return
|
||||
if(ctx->done || ctx->error) return;
|
||||
|
||||
// Recursively getting events until done or has value
|
||||
if(!ctx->event.type) GetEvent(ctx);
|
||||
if(ctx->Level <= start_level) return; // No longer in RSF Domain
|
||||
while(!EventIsScalar(ctx)){
|
||||
if(ctx->done || ctx->error) return;
|
||||
if(ctx->Level <= start_level) return; // No longer in RSF Domain
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
goto CHECK_Group;
|
||||
}
|
||||
|
||||
void GET_Option(ctr_yaml_context *ctx, rsf_settings *rsf)
|
||||
{
|
||||
/* Checking That Group is in a map */
|
||||
if(!CheckMappingEvent(ctx)) return;
|
||||
u32 InitLevel = ctx->Level;
|
||||
/* Checking each child */
|
||||
GetEvent(ctx);
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return;
|
||||
// Handle childs
|
||||
if(cmpYamlValue("AllowUnalignedSection",ctx)) SetBoolYAMLValue(&rsf->Option.AllowUnalignedSection,"AllowUnalignedSection",ctx);
|
||||
else if(cmpYamlValue("MediaFootPadding",ctx)) SetBoolYAMLValue(&rsf->Option.MediaFootPadding,"MediaFootPadding",ctx);
|
||||
else if(cmpYamlValue("EnableCrypt",ctx)) SetBoolYAMLValue(&rsf->Option.EnableCrypt,"EnableCrypt",ctx);
|
||||
else if(cmpYamlValue("EnableCompress",ctx)) SetBoolYAMLValue(&rsf->Option.EnableCompress,"EnableCompress",ctx);
|
||||
else if(cmpYamlValue("FreeProductCode",ctx)) SetBoolYAMLValue(&rsf->Option.FreeProductCode,"FreeProductCode",ctx);
|
||||
else if(cmpYamlValue("UseOnSD",ctx)) SetBoolYAMLValue(&rsf->Option.UseOnSD,"UseOnSD",ctx);
|
||||
else{
|
||||
fprintf(stderr,"[RSF ERROR] Unrecognised key '%s'\n",GetYamlString(ctx));
|
||||
ctx->error = YAML_UNKNOWN_KEY;
|
||||
FinishEvent(ctx);
|
||||
return;
|
||||
}
|
||||
// Finish event start next
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
}
|
||||
|
||||
void GET_AccessControlInfo(ctr_yaml_context *ctx, rsf_settings *rsf)
|
||||
{
|
||||
/* Checking That Group is in a map */
|
||||
if(!CheckMappingEvent(ctx)) return;
|
||||
u32 InitLevel = ctx->Level;
|
||||
/* Checking each child */
|
||||
GetEvent(ctx);
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return;
|
||||
// Handle childs
|
||||
if(cmpYamlValue("DisableDebug",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.DisableDebug,"DisableDebug",ctx);
|
||||
else if(cmpYamlValue("EnableForceDebug",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.EnableForceDebug,"EnableForceDebug",ctx);
|
||||
else if(cmpYamlValue("CanWriteSharedPage",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.CanWriteSharedPage,"CanWriteSharedPage",ctx);
|
||||
else if(cmpYamlValue("CanUsePrivilegedPriority",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.CanUsePrivilegedPriority,"CanUsePrivilegedPriority",ctx);
|
||||
else if(cmpYamlValue("CanUseNonAlphabetAndNumber",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.CanUseNonAlphabetAndNumber,"CanUseNonAlphabetAndNumber",ctx);
|
||||
else if(cmpYamlValue("PermitMainFunctionArgument",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.PermitMainFunctionArgument,"PermitMainFunctionArgument",ctx);
|
||||
else if(cmpYamlValue("CanShareDeviceMemory",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.CanShareDeviceMemory,"CanShareDeviceMemory",ctx);
|
||||
else if(cmpYamlValue("UseOtherVariationSaveData",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.UseOtherVariationSaveData,"UseOtherVariationSaveData",ctx);
|
||||
else if(cmpYamlValue("RunnableOnSleep",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.RunnableOnSleep,"RunnableOnSleep",ctx);
|
||||
else if(cmpYamlValue("SpecialMemoryArrange",ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.SpecialMemoryArrange,"SpecialMemoryArrange",ctx);
|
||||
else if(cmpYamlValue("CanAccessCore2", ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.CanAccessCore2, "CanAccessCore2", ctx);
|
||||
else if(cmpYamlValue("UseExtSaveData", ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.UseExtSaveData, "UseExtSaveData", ctx);
|
||||
else if(cmpYamlValue("EnableL2Cache", ctx)) SetBoolYAMLValue(&rsf->AccessControlInfo.EnableL2Cache, "EnableL2Cache", ctx);
|
||||
|
||||
|
||||
else if(cmpYamlValue("IdealProcessor",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.IdealProcessor,"IdealProcessor",ctx,0);
|
||||
else if(cmpYamlValue("Priority",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.Priority,"Priority",ctx,0);
|
||||
else if(cmpYamlValue("MemoryType",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.MemoryType,"MemoryType",ctx,0);
|
||||
else if(cmpYamlValue("SystemMode",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.SystemMode,"SystemMode",ctx,0);
|
||||
else if(cmpYamlValue("SystemModeExt", ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.SystemModeExt, "SystemModeExt", ctx, 0);
|
||||
else if(cmpYamlValue("CpuSpeed", ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.CpuSpeed, "CpuSpeed", ctx, 0);
|
||||
else if(cmpYamlValue("CoreVersion",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.CoreVersion,"CoreVersion",ctx,0);
|
||||
else if(cmpYamlValue("HandleTableSize",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.HandleTableSize,"HandleTableSize",ctx,0);
|
||||
else if(cmpYamlValue("SystemSaveDataId1",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.SystemSaveDataId1,"SystemSaveDataId1",ctx,0);
|
||||
else if(cmpYamlValue("SystemSaveDataId2",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.SystemSaveDataId2,"SystemSaveDataId2",ctx,0);
|
||||
else if(cmpYamlValue("OtherUserSaveDataId1",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.OtherUserSaveDataId1,"OtherUserSaveDataId1",ctx,0);
|
||||
else if(cmpYamlValue("OtherUserSaveDataId2",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.OtherUserSaveDataId2,"OtherUserSaveDataId2",ctx,0);
|
||||
else if(cmpYamlValue("OtherUserSaveDataId3",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.OtherUserSaveDataId3,"OtherUserSaveDataId3",ctx,0);
|
||||
else if(cmpYamlValue("ExtSaveDataId",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.ExtSaveDataId,"ExtSaveDataId",ctx,0);
|
||||
else if(cmpYamlValue("AffinityMask",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.AffinityMask,"AffinityMask",ctx,0);
|
||||
else if(cmpYamlValue("DescVersion",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.DescVersion,"DescVersion",ctx,0);
|
||||
else if(cmpYamlValue("ResourceLimitCategory",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.ResourceLimitCategory,"ResourceLimitCategory",ctx,0);
|
||||
else if(cmpYamlValue("ReleaseKernelMajor",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.ReleaseKernelMajor,"ReleaseKernelMajor",ctx,0);
|
||||
else if(cmpYamlValue("ReleaseKernelMinor",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.ReleaseKernelMinor,"ReleaseKernelMinor",ctx,0);
|
||||
else if(cmpYamlValue("MaxCpu",ctx)) SetSimpleYAMLValue(&rsf->AccessControlInfo.MaxCpu,"MaxCpu",ctx,0);
|
||||
|
||||
|
||||
else if(cmpYamlValue("MemoryMapping",ctx)) rsf->AccessControlInfo.MemoryMappingNum = SetYAMLSequence(&rsf->AccessControlInfo.MemoryMapping,"MemoryMapping",ctx);
|
||||
else if(cmpYamlValue("IORegisterMapping",ctx)) rsf->AccessControlInfo.IORegisterMappingNum = SetYAMLSequence(&rsf->AccessControlInfo.IORegisterMapping,"IORegisterMapping",ctx);
|
||||
else if(cmpYamlValue("FileSystemAccess",ctx)) rsf->AccessControlInfo.FileSystemAccessNum = SetYAMLSequence(&rsf->AccessControlInfo.FileSystemAccess,"FileSystemAccess",ctx);
|
||||
else if(cmpYamlValue("IoAccessControl",ctx)) rsf->AccessControlInfo.IoAccessControlNum = SetYAMLSequence(&rsf->AccessControlInfo.IoAccessControl,"IoAccessControl",ctx);
|
||||
else if(cmpYamlValue("InterruptNumbers",ctx)) rsf->AccessControlInfo.InterruptNumbersNum = SetYAMLSequence(&rsf->AccessControlInfo.InterruptNumbers,"InterruptNumbers",ctx);
|
||||
else if(cmpYamlValue("SystemCallAccess",ctx)) rsf->AccessControlInfo.SystemCallAccessNum = SetYAMLSequenceFromMapping(&rsf->AccessControlInfo.SystemCallAccess,"SystemCallAccess",ctx,false);
|
||||
else if(cmpYamlValue("ServiceAccessControl",ctx)) rsf->AccessControlInfo.ServiceAccessControlNum = SetYAMLSequence(&rsf->AccessControlInfo.ServiceAccessControl,"ServiceAccessControl",ctx);
|
||||
else if(cmpYamlValue("AccessibleSaveDataIds",ctx)) rsf->AccessControlInfo.AccessibleSaveDataIdsNum = SetYAMLSequence(&rsf->AccessControlInfo.AccessibleSaveDataIds,"AccessibleSaveDataIds",ctx);
|
||||
|
||||
else{
|
||||
fprintf(stderr,"[RSF ERROR] Unrecognised key '%s'\n",GetYamlString(ctx));
|
||||
ctx->error = YAML_UNKNOWN_KEY;
|
||||
FinishEvent(ctx);
|
||||
return;
|
||||
}
|
||||
// Finish event start next
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
}
|
||||
|
||||
void GET_SystemControlInfo(ctr_yaml_context *ctx, rsf_settings *rsf)
|
||||
{
|
||||
/* Checking That Group is in a map */
|
||||
if(!CheckMappingEvent(ctx)) return;
|
||||
u32 InitLevel = ctx->Level;
|
||||
/* Checking each child */
|
||||
GetEvent(ctx);
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return;
|
||||
// Handle childs
|
||||
|
||||
if(cmpYamlValue("AppType",ctx)) SetSimpleYAMLValue(&rsf->SystemControlInfo.AppType,"AppType",ctx,0);
|
||||
else if(cmpYamlValue("StackSize",ctx)) SetSimpleYAMLValue(&rsf->SystemControlInfo.StackSize,"StackSize",ctx,0);
|
||||
else if(cmpYamlValue("RemasterVersion",ctx)) SetSimpleYAMLValue(&rsf->SystemControlInfo.RemasterVersion,"RemasterVersion",ctx,0);
|
||||
else if(cmpYamlValue("JumpId",ctx)) SetSimpleYAMLValue(&rsf->SystemControlInfo.JumpId,"JumpId",ctx,0);
|
||||
else if(cmpYamlValue("SaveDataSize",ctx)) SetSimpleYAMLValue(&rsf->SystemControlInfo.SaveDataSize,"SaveDataSize",ctx,0);
|
||||
else if(cmpYamlValue("Dependency",ctx)) rsf->SystemControlInfo.DependencyNum = SetYAMLSequenceFromMapping(&rsf->SystemControlInfo.Dependency,"Dependency",ctx,false);
|
||||
else{
|
||||
fprintf(stderr,"[RSF ERROR] Unrecognised key '%s'\n",GetYamlString(ctx));
|
||||
ctx->error = YAML_UNKNOWN_KEY;
|
||||
FinishEvent(ctx);
|
||||
return;
|
||||
}
|
||||
// Finish event start next
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
}
|
||||
|
||||
void GET_BasicInfo(ctr_yaml_context *ctx, rsf_settings *rsf)
|
||||
{
|
||||
/* Checking That Group is in a map */
|
||||
if(!CheckMappingEvent(ctx)) return;
|
||||
u32 InitLevel = ctx->Level;
|
||||
/* Checking each child */
|
||||
GetEvent(ctx);
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return;
|
||||
// Handle childs
|
||||
if(cmpYamlValue("Title",ctx)) SetSimpleYAMLValue(&rsf->BasicInfo.Title,"Title",ctx,0);
|
||||
else if(cmpYamlValue("CompanyCode",ctx)) SetSimpleYAMLValue(&rsf->BasicInfo.CompanyCode,"CompanyCode",ctx,0);
|
||||
else if(cmpYamlValue("ProductCode",ctx)) SetSimpleYAMLValue(&rsf->BasicInfo.ProductCode,"ProductCode",ctx,0);
|
||||
else if(cmpYamlValue("ContentType",ctx)) SetSimpleYAMLValue(&rsf->BasicInfo.ContentType,"ContentType",ctx,0);
|
||||
else if(cmpYamlValue("Logo",ctx)) SetSimpleYAMLValue(&rsf->BasicInfo.Logo,"Logo",ctx,0);
|
||||
else{
|
||||
fprintf(stderr,"[RSF ERROR] Unrecognised key '%s'\n",GetYamlString(ctx));
|
||||
ctx->error = YAML_UNKNOWN_KEY;
|
||||
FinishEvent(ctx);
|
||||
return;
|
||||
}
|
||||
// Finish event start next
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
}
|
||||
|
||||
void GET_RomFs(ctr_yaml_context *ctx, rsf_settings *rsf)
|
||||
{
|
||||
/* Checking That Group is in a map */
|
||||
if(!CheckMappingEvent(ctx)) return;
|
||||
u32 InitLevel = ctx->Level;
|
||||
/* Checking each child */
|
||||
GetEvent(ctx);
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return;
|
||||
// Handle childs
|
||||
|
||||
if(cmpYamlValue("RootPath",ctx)) SetSimpleYAMLValue(&rsf->RomFs.RootPath,"RootPath",ctx,0);
|
||||
|
||||
else if(cmpYamlValue("DefaultReject",ctx)) rsf->RomFs.DefaultRejectNum = SetYAMLSequence(&rsf->RomFs.DefaultReject,"DefaultReject",ctx);
|
||||
else if(cmpYamlValue("Reject",ctx)) rsf->RomFs.RejectNum = SetYAMLSequence(&rsf->RomFs.Reject,"Reject",ctx);
|
||||
else if(cmpYamlValue("Include",ctx)) rsf->RomFs.IncludeNum = SetYAMLSequence(&rsf->RomFs.Include,"Include",ctx);
|
||||
else if(cmpYamlValue("File",ctx)) rsf->RomFs.FileNum = SetYAMLSequence(&rsf->RomFs.File,"File",ctx);
|
||||
|
||||
else{
|
||||
fprintf(stderr,"[RSF ERROR] Unrecognised key '%s'\n",GetYamlString(ctx));
|
||||
ctx->error = YAML_UNKNOWN_KEY;
|
||||
FinishEvent(ctx);
|
||||
return;
|
||||
}
|
||||
// Finish event start next
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
}
|
||||
|
||||
void GET_TitleInfo(ctr_yaml_context *ctx, rsf_settings *rsf)
|
||||
{
|
||||
/* Checking That Group is in a map */
|
||||
if(!CheckMappingEvent(ctx)) return;
|
||||
u32 InitLevel = ctx->Level;
|
||||
/* Checking each child */
|
||||
GetEvent(ctx);
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return;
|
||||
// Handle childs
|
||||
|
||||
if (cmpYamlValue("Platform", ctx)) SetSimpleYAMLValue(&rsf->TitleInfo.Platform, "Platform", ctx, 0);
|
||||
else if(cmpYamlValue("Category",ctx)) SetSimpleYAMLValue(&rsf->TitleInfo.Category,"Category",ctx,0);
|
||||
else if(cmpYamlValue("UniqueId",ctx)) SetSimpleYAMLValue(&rsf->TitleInfo.UniqueId,"UniqueId",ctx,0);
|
||||
else if(cmpYamlValue("Version",ctx)) SetSimpleYAMLValue(&rsf->TitleInfo.Version,"Version",ctx,0);
|
||||
else if(cmpYamlValue("ContentsIndex",ctx)) SetSimpleYAMLValue(&rsf->TitleInfo.ContentsIndex,"ContentsIndex",ctx,0);
|
||||
else if(cmpYamlValue("Variation",ctx)) SetSimpleYAMLValue(&rsf->TitleInfo.Variation,"Variation",ctx,0);
|
||||
else if(cmpYamlValue("ChildIndex",ctx)) SetSimpleYAMLValue(&rsf->TitleInfo.ChildIndex,"ChildIndex",ctx,0);
|
||||
else if(cmpYamlValue("DemoIndex",ctx)) SetSimpleYAMLValue(&rsf->TitleInfo.DemoIndex,"DemoIndex",ctx,0);
|
||||
else if(cmpYamlValue("TargetCategory",ctx)) SetSimpleYAMLValue(&rsf->TitleInfo.TargetCategory,"TargetCategory",ctx,0);
|
||||
|
||||
else if(cmpYamlValue("CategoryFlags",ctx)) rsf->TitleInfo.CategoryFlagsNum = SetYAMLSequence(&rsf->TitleInfo.CategoryFlags,"CategoryFlags",ctx);
|
||||
|
||||
else{
|
||||
fprintf(stderr,"[RSF ERROR] Unrecognised key '%s'\n",GetYamlString(ctx));
|
||||
ctx->error = YAML_UNKNOWN_KEY;
|
||||
FinishEvent(ctx);
|
||||
return;
|
||||
}
|
||||
// Finish event start next
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
}
|
||||
|
||||
void GET_CardInfo(ctr_yaml_context *ctx, rsf_settings *rsf)
|
||||
{
|
||||
/* Checking That Group is in a map */
|
||||
if(!CheckMappingEvent(ctx)) return;
|
||||
u32 InitLevel = ctx->Level;
|
||||
/* Checking each child */
|
||||
GetEvent(ctx);
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return;
|
||||
// Handle childs
|
||||
|
||||
if(cmpYamlValue("WritableAddress",ctx)) SetSimpleYAMLValue(&rsf->CardInfo.WritableAddress,"WritableAddress",ctx,0);
|
||||
else if(cmpYamlValue("CardType",ctx)) SetSimpleYAMLValue(&rsf->CardInfo.CardType,"CardType",ctx,0);
|
||||
else if(cmpYamlValue("CryptoType",ctx)) SetSimpleYAMLValue(&rsf->CardInfo.CryptoType,"CryptoType",ctx,0);
|
||||
else if(cmpYamlValue("CardDevice",ctx)) SetSimpleYAMLValue(&rsf->CardInfo.CardDevice,"CardDevice",ctx,0);
|
||||
else if(cmpYamlValue("MediaType",ctx)) SetSimpleYAMLValue(&rsf->CardInfo.MediaType,"MediaType",ctx,0);
|
||||
else if(cmpYamlValue("MediaSize",ctx)) SetSimpleYAMLValue(&rsf->CardInfo.MediaSize,"MediaSize",ctx,0);
|
||||
else if(cmpYamlValue("BackupWriteWaitTime",ctx)) SetSimpleYAMLValue(&rsf->CardInfo.BackupWriteWaitTime,"BackupWriteWaitTime",ctx,0);
|
||||
else if(cmpYamlValue("SaveCrypto",ctx)) SetSimpleYAMLValue(&rsf->CardInfo.SaveCrypto,"SaveCrypto",ctx,0);
|
||||
|
||||
else{
|
||||
fprintf(stderr,"[RSF ERROR] Unrecognised key '%s'\n",GetYamlString(ctx));
|
||||
ctx->error = YAML_UNKNOWN_KEY;
|
||||
FinishEvent(ctx);
|
||||
return;
|
||||
}
|
||||
// Finish event start next
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
}
|
||||
|
||||
void GET_CommonHeaderKey(ctr_yaml_context *ctx, rsf_settings *rsf)
|
||||
{
|
||||
/* Checking That Group is in a map */
|
||||
if(!CheckMappingEvent(ctx)) return;
|
||||
u32 InitLevel = ctx->Level;
|
||||
/* Checking each child */
|
||||
GetEvent(ctx);
|
||||
rsf->CommonHeaderKey.Found = true;
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return;
|
||||
// Handle childs
|
||||
|
||||
if(cmpYamlValue("D",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.D,"D",ctx,0);
|
||||
else if(cmpYamlValue("P",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.P,"P",ctx,0);
|
||||
else if(cmpYamlValue("Q",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.Q,"Q",ctx,0);
|
||||
else if(cmpYamlValue("DP",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.DP,"DP",ctx,0);
|
||||
else if(cmpYamlValue("DQ",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.DQ,"DQ",ctx,0);
|
||||
else if(cmpYamlValue("InverseQ",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.InverseQ,"InverseQ",ctx,0);
|
||||
else if(cmpYamlValue("Modulus",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.Modulus,"Modulus",ctx,0);
|
||||
else if(cmpYamlValue("Exponent",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.Exponent,"Exponent",ctx,0);
|
||||
else if(cmpYamlValue("Signature",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.AccCtlDescSign,"Signature",ctx,0);
|
||||
else if(cmpYamlValue("Descriptor",ctx)) SetSimpleYAMLValue(&rsf->CommonHeaderKey.AccCtlDescBin,"Descriptor",ctx,0);
|
||||
|
||||
else{
|
||||
fprintf(stderr,"[RSF ERROR] Unrecognised key '%s'\n",GetYamlString(ctx));
|
||||
ctx->error = YAML_UNKNOWN_KEY;
|
||||
FinishEvent(ctx);
|
||||
return;
|
||||
}
|
||||
// Finish event start next
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
}
|
||||
|
||||
void free_RsfSettings(rsf_settings *set)
|
||||
{
|
||||
//AccessControlInfo
|
||||
free(set->AccessControlInfo.IdealProcessor);
|
||||
free(set->AccessControlInfo.Priority);
|
||||
free(set->AccessControlInfo.MemoryType);
|
||||
free(set->AccessControlInfo.SystemMode);
|
||||
free(set->AccessControlInfo.SystemModeExt);
|
||||
free(set->AccessControlInfo.CpuSpeed);
|
||||
free(set->AccessControlInfo.CoreVersion);
|
||||
free(set->AccessControlInfo.HandleTableSize);
|
||||
free(set->AccessControlInfo.SystemSaveDataId1);
|
||||
free(set->AccessControlInfo.SystemSaveDataId2);
|
||||
free(set->AccessControlInfo.OtherUserSaveDataId1);
|
||||
free(set->AccessControlInfo.OtherUserSaveDataId2);
|
||||
free(set->AccessControlInfo.OtherUserSaveDataId3);
|
||||
free(set->AccessControlInfo.ExtSaveDataId);
|
||||
free(set->AccessControlInfo.AffinityMask);
|
||||
free(set->AccessControlInfo.DescVersion);
|
||||
free(set->AccessControlInfo.ResourceLimitCategory);
|
||||
free(set->AccessControlInfo.ReleaseKernelMajor);
|
||||
free(set->AccessControlInfo.ReleaseKernelMinor);
|
||||
free(set->AccessControlInfo.MaxCpu);
|
||||
|
||||
for(u32 i = 0; i < set->AccessControlInfo.MemoryMappingNum; i++){
|
||||
free(set->AccessControlInfo.MemoryMapping[i]);
|
||||
}
|
||||
free(set->AccessControlInfo.MemoryMapping);
|
||||
|
||||
for(u32 i = 0; i < set->AccessControlInfo.IORegisterMappingNum; i++){
|
||||
free(set->AccessControlInfo.IORegisterMapping[i]);
|
||||
}
|
||||
free(set->AccessControlInfo.IORegisterMapping);
|
||||
|
||||
for(u32 i = 0; i < set->AccessControlInfo.FileSystemAccessNum; i++){
|
||||
free(set->AccessControlInfo.FileSystemAccess[i]);
|
||||
}
|
||||
free(set->AccessControlInfo.FileSystemAccess);
|
||||
|
||||
for(u32 i = 0; i < set->AccessControlInfo.IoAccessControlNum; i++){
|
||||
free(set->AccessControlInfo.IoAccessControl[i]);
|
||||
}
|
||||
free(set->AccessControlInfo.IoAccessControl);
|
||||
|
||||
for(u32 i = 0; i < set->AccessControlInfo.InterruptNumbersNum; i++){
|
||||
free(set->AccessControlInfo.InterruptNumbers[i]);
|
||||
}
|
||||
free(set->AccessControlInfo.InterruptNumbers);
|
||||
|
||||
for(u32 i = 0; i < set->AccessControlInfo.SystemCallAccessNum; i++){
|
||||
free(set->AccessControlInfo.SystemCallAccess[i]);
|
||||
}
|
||||
free(set->AccessControlInfo.SystemCallAccess);
|
||||
|
||||
for(u32 i = 0; i < set->AccessControlInfo.ServiceAccessControlNum; i++){
|
||||
free(set->AccessControlInfo.ServiceAccessControl[i]);
|
||||
}
|
||||
free(set->AccessControlInfo.ServiceAccessControl);
|
||||
|
||||
for(u32 i = 0; i < set->AccessControlInfo.AccessibleSaveDataIdsNum; i++){
|
||||
free(set->AccessControlInfo.AccessibleSaveDataIds[i]);
|
||||
}
|
||||
free(set->AccessControlInfo.AccessibleSaveDataIds);
|
||||
|
||||
//SystemControlInfo
|
||||
free(set->SystemControlInfo.AppType);
|
||||
free(set->SystemControlInfo.StackSize);
|
||||
free(set->SystemControlInfo.RemasterVersion);
|
||||
free(set->SystemControlInfo.SaveDataSize);
|
||||
free(set->SystemControlInfo.JumpId);
|
||||
|
||||
for(u32 i = 0; i < set->SystemControlInfo.DependencyNum; i++){
|
||||
free(set->SystemControlInfo.Dependency[i]);
|
||||
}
|
||||
free(set->SystemControlInfo.Dependency);
|
||||
|
||||
//BasicInfo
|
||||
free(set->BasicInfo.Title);
|
||||
free(set->BasicInfo.CompanyCode);
|
||||
free(set->BasicInfo.ProductCode);
|
||||
free(set->BasicInfo.ContentType);
|
||||
free(set->BasicInfo.Logo);
|
||||
|
||||
//Rom
|
||||
free(set->RomFs.RootPath);
|
||||
|
||||
for(u32 i = 0; i < set->RomFs.DefaultRejectNum; i++){
|
||||
free(set->RomFs.DefaultReject[i]);
|
||||
}
|
||||
free(set->RomFs.DefaultReject);
|
||||
|
||||
for(u32 i = 0; i < set->RomFs.RejectNum; i++){
|
||||
free(set->RomFs.Reject[i]);
|
||||
}
|
||||
free(set->RomFs.Reject);
|
||||
|
||||
for(u32 i = 0; i < set->RomFs.IncludeNum; i++){
|
||||
free(set->RomFs.Include[i]);
|
||||
}
|
||||
free(set->RomFs.Include);
|
||||
|
||||
for(u32 i = 0; i < set->RomFs.FileNum; i++){
|
||||
free(set->RomFs.File[i]);
|
||||
}
|
||||
free(set->RomFs.File);
|
||||
|
||||
//TitleInfo
|
||||
free(set->TitleInfo.Platform);
|
||||
free(set->TitleInfo.Category);
|
||||
free(set->TitleInfo.UniqueId);
|
||||
free(set->TitleInfo.Version);
|
||||
free(set->TitleInfo.ContentsIndex);
|
||||
free(set->TitleInfo.Variation);
|
||||
free(set->TitleInfo.ChildIndex);
|
||||
free(set->TitleInfo.DemoIndex);
|
||||
free(set->TitleInfo.TargetCategory);
|
||||
|
||||
for(u32 i = 0; i < set->TitleInfo.CategoryFlagsNum; i++){
|
||||
free(set->TitleInfo.CategoryFlags[i]);
|
||||
}
|
||||
free(set->TitleInfo.CategoryFlags);
|
||||
|
||||
//CardInfo
|
||||
free(set->CardInfo.WritableAddress);
|
||||
free(set->CardInfo.CardType);
|
||||
free(set->CardInfo.CryptoType);
|
||||
free(set->CardInfo.CardDevice);
|
||||
free(set->CardInfo.MediaType);
|
||||
free(set->CardInfo.MediaSize);
|
||||
free(set->CardInfo.BackupWriteWaitTime);
|
||||
free(set->CardInfo.SaveCrypto);
|
||||
|
||||
//CommonHeaderKey
|
||||
free(set->CommonHeaderKey.D);
|
||||
free(set->CommonHeaderKey.P);
|
||||
free(set->CommonHeaderKey.Q);
|
||||
free(set->CommonHeaderKey.DP);
|
||||
free(set->CommonHeaderKey.DQ);
|
||||
free(set->CommonHeaderKey.InverseQ);
|
||||
free(set->CommonHeaderKey.Modulus);
|
||||
free(set->CommonHeaderKey.Exponent);
|
||||
free(set->CommonHeaderKey.AccCtlDescSign);
|
||||
free(set->CommonHeaderKey.AccCtlDescBin);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void EvaluateRSF(rsf_settings *rsf, ctr_yaml_context *ctx);
|
||||
void free_RsfSettings(rsf_settings *set);
|
||||
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 gameTitle[0xC];
|
||||
u8 gameCode[4];
|
||||
u8 makerCode[2];
|
||||
u8 unitCode;
|
||||
u8 encryptionSeedSelect;
|
||||
u8 deviceCapacity;
|
||||
u8 reserved0[9];
|
||||
u8 romVersion;
|
||||
u8 internalFlag;
|
||||
u8 arm9RomOffset[4];
|
||||
u8 arm9EntryAddress[4];
|
||||
u8 arm9RamAddress[4];
|
||||
u8 arm9Size[4];
|
||||
u8 arm7RomOffset[4];
|
||||
u8 arm7EntryAddress[4];
|
||||
u8 arm7RamAddress[4];
|
||||
u8 arm7Size[4];
|
||||
u8 fntOffset[4];
|
||||
u8 fntSize[4];
|
||||
u8 fatOffset[4];
|
||||
u8 fatSize[4];
|
||||
u8 arm9OverlayOffset[4];
|
||||
u8 arm9OverlaySize[4];
|
||||
u8 arm7OverlayOffset[4];
|
||||
u8 arm7OverlaySize[4];
|
||||
u8 normalCardControlRegSettings[4];
|
||||
u8 secureCardControlRegSettings[4];
|
||||
u8 icon_bannerOffset[4];
|
||||
u8 secureAreaCrc[2];
|
||||
u8 secure_transfer_timeout[2];
|
||||
u8 arm9Autoload[4];
|
||||
u8 arm7Autoload[4];
|
||||
u8 secureDisable[8];
|
||||
u8 ntrRomSize[4];
|
||||
u8 headerSize[4];
|
||||
u8 reserved1[0x38];
|
||||
u8 nintendoLogo[0x9C];
|
||||
u8 nintendoLogoCrc[2];
|
||||
u8 headerCrc[2];
|
||||
u8 debugReserved[0x20];
|
||||
|
||||
//TWL Only Data
|
||||
u8 configSettings[0x34];
|
||||
u8 accessControl[4];
|
||||
u8 arm7ScfgExtMask[4];
|
||||
u8 reserved_flags[4];
|
||||
u8 arm9iRomOffset[4];
|
||||
u8 reserved2[4];
|
||||
u8 arm9iLoadAddress[4];
|
||||
u8 arm9iSize[4];
|
||||
u8 arm7iRomOffset[4];
|
||||
u8 struct_param_baseAddress[4];
|
||||
u8 arm7iLoadAddress[4];
|
||||
u8 arm7iSize[4];
|
||||
u8 digest_ntrRegionOffset[4];
|
||||
u8 digest_ntrRegionSize[4];
|
||||
u8 digest_twlRegionOffset[4];
|
||||
u8 digest_twlRegionSize[4];
|
||||
u8 digestSectorHashtableOffset[4];
|
||||
u8 digestSectorHashtableSize[4];
|
||||
u8 digest_blockHashtableOffset[4];
|
||||
u8 digest_blockHashtableSize[4];
|
||||
u8 digestSectorSize[4];
|
||||
u8 digest_blockSectorcount[4];
|
||||
u8 reserved3[8];
|
||||
u8 twlRomSize[8];
|
||||
u8 unknown[8];
|
||||
u8 modcryptArea1Offset[4];
|
||||
u8 modcryptArea1Size[4];
|
||||
u8 modcryptArea2Offset[4];
|
||||
u8 modcryptArea2Size[4];
|
||||
u8 title_id[8];
|
||||
u8 pubSaveDataSize[4];
|
||||
u8 privSaveDataSize[4];
|
||||
u8 reserved4[0xC0];
|
||||
|
||||
// TWL and Signed NTR
|
||||
u8 arm9WithSecAreaSha1Hmac[0x14];
|
||||
u8 arm7Sha1Hmac[0x14];
|
||||
u8 digestMasterSha1Hmac[0x14];
|
||||
u8 bannerSha1Hmac[0x14];
|
||||
u8 arm9iSha1Hmac[0x14];
|
||||
u8 arm7iSha1Hmac[0x14];
|
||||
u8 reserved5[0x28];
|
||||
u8 arm9Sha1Hmac[0x14];
|
||||
u8 reserved6[0xA4C];
|
||||
u8 reserved7[0x180];
|
||||
u8 signature[0x80];
|
||||
} srl_hdr;
|
||||
@@ -0,0 +1,208 @@
|
||||
#include "lib.h"
|
||||
#include "cia_build.h"
|
||||
#include "tik_build.h"
|
||||
|
||||
// Private Prototypes
|
||||
int SetupTicketBuffer(cia_settings *set);
|
||||
void SetupTicketHeader(tik_hdr *hdr, cia_settings *ciaset);
|
||||
int SignTicketHeader(buffer_struct *tik, keys_struct *keys);
|
||||
void SetLimits(tik_hdr *hdr, cia_settings *ciaset);
|
||||
u32 GetContentIndexSegNum(cia_settings *set);
|
||||
void SetContentIndexHeader(tik_content_index_hdr *hdr, cia_settings *set);
|
||||
void SetContentIndexData(tik_content_index_struct *data, cia_settings *set);
|
||||
|
||||
int CryptTitleKey(u8 *input, u8 *output, u8 *titleId, keys_struct *keys, u8 mode);
|
||||
|
||||
int BuildTicket(cia_settings *set)
|
||||
{
|
||||
if(SetupTicketBuffer(set))
|
||||
return MEM_ERROR;
|
||||
|
||||
// Setting Ticket Struct Ptrs
|
||||
buffer_struct *tik = &set->ciaSections.tik;
|
||||
|
||||
tik_hdr *hdr = (tik_hdr*) (tik->buffer + sizeof(tik_signature));
|
||||
tik_content_index_hdr *idxHdr = (tik_content_index_hdr*) (tik->buffer + sizeof(tik_signature) + sizeof(tik_hdr));
|
||||
tik_content_index_struct *idxData = (tik_content_index_struct*) (tik->buffer + sizeof(tik_signature) + sizeof(tik_hdr) + sizeof(tik_content_index_hdr));
|
||||
|
||||
|
||||
SetupTicketHeader(hdr,set);
|
||||
SetContentIndexHeader(idxHdr,set);
|
||||
SetContentIndexData(idxData,set);
|
||||
|
||||
return SignTicketHeader(tik,set->keys);
|
||||
}
|
||||
|
||||
int SetupTicketBuffer(cia_settings *set)
|
||||
{
|
||||
buffer_struct *tik = &set->ciaSections.tik;
|
||||
|
||||
tik->size = sizeof(tik_signature) + sizeof(tik_hdr) + sizeof(tik_content_index_hdr) + sizeof(tik_content_index_struct)*GetContentIndexSegNum(set);
|
||||
tik->buffer = calloc(1,tik->size);
|
||||
if(!tik->buffer) {
|
||||
fprintf(stderr,"[TIK ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetupTicketHeader(tik_hdr *hdr, cia_settings *ciaset)
|
||||
{
|
||||
clrmem(hdr,sizeof(tik_hdr));
|
||||
|
||||
memcpy(hdr->issuer,ciaset->tik.issuer,0x40);
|
||||
hdr->formatVersion = ciaset->tik.formatVersion;
|
||||
hdr->caCrlVersion = ciaset->cert.caCrlVersion;
|
||||
hdr->signerCrlVersion = ciaset->cert.signerCrlVersion;
|
||||
u64_to_u8(hdr->ticketId,ciaset->tik.ticketId,BE);
|
||||
u32_to_u8(hdr->deviceId,ciaset->tik.deviceId,BE);
|
||||
u64_to_u8(hdr->titleId,ciaset->common.titleId,BE);
|
||||
u16_to_u8(hdr->ticketVersion,ciaset->tik.version,BE);
|
||||
hdr->licenceType = ciaset->tik.licenceType;
|
||||
hdr->keyId = ciaset->keys->aes.currentCommonKey;
|
||||
u32_to_u8(hdr->eshopAccId,ciaset->tik.eshopAccId,BE);
|
||||
hdr->audit = ciaset->tik.audit;
|
||||
SetLimits(hdr,ciaset);
|
||||
|
||||
// Crypt TitleKey
|
||||
if(ciaset->content.encryptCia)
|
||||
CryptTitleKey(ciaset->common.titleKey, hdr->encryptedTitleKey, hdr->titleId, ciaset->keys, ENC);
|
||||
else
|
||||
rndset(hdr->encryptedTitleKey,AES_128_KEY_SIZE);
|
||||
}
|
||||
|
||||
int SignTicketHeader(buffer_struct *tik, keys_struct *keys)
|
||||
{
|
||||
tik_signature *sig = (tik_signature*)tik->buffer;
|
||||
u8 *data = tik->buffer + sizeof(tik_signature);
|
||||
u32 len = tik->size - sizeof(tik_signature);
|
||||
|
||||
|
||||
clrmem(sig,sizeof(tik_signature));
|
||||
u32_to_u8(sig->sigType,RSA_2048_SHA256,BE);
|
||||
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.xs) == false)
|
||||
{
|
||||
printf("[TIK WARNING] Failed to sign header (key was incomplete)\n");
|
||||
memset(sig->data, 0xFF, 0x100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rsa_ret = RsaSignVerify(data, len, sig->data, keys->rsa.xs.pub, keys->rsa.xs.pvt, RSA_2048_SHA256, CTR_RSA_SIGN);
|
||||
if (rsa_ret != 0)
|
||||
{
|
||||
printf("[TIK WARNING] Failed to sign header (mbedtls error = -0x%x)\n", -rsa_ret);
|
||||
memset(sig->data, 0xFF, 0x100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CryptTitleKey(u8 *input, u8 *output, u8 *titleId, keys_struct *keys, u8 mode)
|
||||
{
|
||||
//Generating IV
|
||||
u8 iv[16];
|
||||
clrmem(&iv,16);
|
||||
memcpy(iv,titleId,0x8);
|
||||
|
||||
//Crypting TitleKey
|
||||
AesCbcCrypt(keys->aes.commonKey[keys->aes.currentCommonKey],iv,input,output,0x10,mode);
|
||||
|
||||
// Return
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetLimits(tik_hdr *hdr, cia_settings *ciaset) // TODO?
|
||||
{
|
||||
memset(hdr->limits,0,0x40);
|
||||
}
|
||||
|
||||
u32 GetContentIndexSegNum(cia_settings *set)
|
||||
{
|
||||
u32 num, level, i;
|
||||
|
||||
num = level = 0;
|
||||
|
||||
for( i = 0; i < set->content.count; i++)
|
||||
{
|
||||
if(set->content.index[i] >= level)
|
||||
{
|
||||
level = roundup(set->content.index[i],0x400);
|
||||
num++;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
void SetContentIndexHeader(tik_content_index_hdr *hdr, cia_settings *set)
|
||||
{
|
||||
u32 hdrSize = sizeof(tik_content_index_hdr);
|
||||
u32 segNum = GetContentIndexSegNum(set);
|
||||
u32 segSize = sizeof(tik_content_index_struct);
|
||||
u32 segTotalSize = segSize * segNum;
|
||||
u32 totalSize = hdrSize + segTotalSize;
|
||||
|
||||
u32_to_u8(hdr->unk0,0x00010014,BE);
|
||||
u32_to_u8(hdr->totalSize,totalSize,BE);
|
||||
u32_to_u8(hdr->unk1,0x00000014,BE);
|
||||
u32_to_u8(hdr->unk2,0x00010014,BE);
|
||||
u32_to_u8(hdr->unk3,0x00000000,BE);
|
||||
u32_to_u8(hdr->hdrSize,hdrSize,BE);
|
||||
u32_to_u8(hdr->segNum,segNum,BE);
|
||||
u32_to_u8(hdr->segSize,segSize,BE);
|
||||
u32_to_u8(hdr->segTotalSize,segTotalSize,BE);
|
||||
u32_to_u8(hdr->unk4,0x00030000,BE);
|
||||
}
|
||||
|
||||
void SetContentIndexData(tik_content_index_struct *data, cia_settings *set)
|
||||
{
|
||||
u32 level, i;
|
||||
int j;
|
||||
|
||||
j = -1;
|
||||
level = 0;
|
||||
|
||||
for( i = 0; i < set->content.count; i++)
|
||||
{
|
||||
if(set->content.index[i] >= level)
|
||||
{
|
||||
level = roundup(set->content.index[i],0x400);
|
||||
j++;
|
||||
u32_to_u8(data[j].level,(set->content.index[i]/0x400)*0x400,BE);
|
||||
}
|
||||
data[j].index[(set->content.index[i] & 0x3ff)/8] |= 1 << (set->content.index[i] & 0x7);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tik_hdr *GetTikHdr(u8 *tik)
|
||||
{
|
||||
u32 sigType = u8_to_u32(tik,BE);
|
||||
|
||||
switch(sigType){
|
||||
case(RSA_4096_SHA1):
|
||||
case(RSA_4096_SHA256):
|
||||
return (tik_hdr*)(tik+0x240);
|
||||
case(RSA_2048_SHA1):
|
||||
case(RSA_2048_SHA256):
|
||||
return (tik_hdr*)(tik+0x140);
|
||||
case(ECC_SHA1):
|
||||
case(ECC_SHA256):
|
||||
return (tik_hdr*)(tik+0x7C);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool GetTikTitleKey(u8 *titleKey, tik_hdr *hdr, keys_struct *keys)
|
||||
{
|
||||
if(keys->aes.commonKey[hdr->keyId] == NULL)
|
||||
return false;
|
||||
|
||||
keys->aes.currentCommonKey = hdr->keyId;
|
||||
|
||||
CryptTitleKey(hdr->encryptedTitleKey, titleKey, hdr->titleId, keys, DEC);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum
|
||||
{
|
||||
lic_Permanent = 0,
|
||||
lic_Demo = 1,
|
||||
lic_Trial = 2,
|
||||
lic_Rental = 3,
|
||||
lic_Subscription = 4,
|
||||
lic_Service = 5,
|
||||
lic_Mask = 15
|
||||
} tik_license_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
right_Permanent = 1,
|
||||
right_Subscription = 2,
|
||||
right_Content = 3,
|
||||
right_ContentConsumption = 4,
|
||||
right_AccessTitle = 5
|
||||
} tik_item_rights;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 unk0[4];
|
||||
u8 totalSize[4];
|
||||
u8 unk1[4];
|
||||
u8 unk2[4];
|
||||
u8 unk3[4];
|
||||
u8 hdrSize[4];
|
||||
u8 segNum[4];
|
||||
u8 segSize[4];
|
||||
u8 segTotalSize[4];
|
||||
u8 unk4[4];
|
||||
} tik_content_index_hdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 level[4];
|
||||
u8 index[0x80];
|
||||
} tik_content_index_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 sigType[4];
|
||||
u8 data[0x100];
|
||||
u8 padding[0x3C];
|
||||
} tik_signature;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 issuer[0x40];
|
||||
u8 eccPubKey[0x3c];
|
||||
u8 formatVersion;
|
||||
u8 caCrlVersion;
|
||||
u8 signerCrlVersion;
|
||||
u8 encryptedTitleKey[0x10];
|
||||
u8 padding0;
|
||||
u8 ticketId[8];
|
||||
u8 deviceId[4];
|
||||
u8 titleId[8];
|
||||
u8 padding1[2];
|
||||
u8 ticketVersion[2];
|
||||
u8 padding2[8];
|
||||
u8 licenceType;
|
||||
u8 keyId;
|
||||
u8 propertyMask[2];
|
||||
u8 customData[0x14];
|
||||
u8 padding3[0x14];
|
||||
u8 eshopAccId[4];
|
||||
u8 padding4;
|
||||
u8 audit;
|
||||
u8 padding5[0x42];
|
||||
u8 limits[0x40];
|
||||
} tik_hdr;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "tik.h"
|
||||
|
||||
// Prototypes
|
||||
int BuildTicket(cia_settings *ciaset);
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "tik.h"
|
||||
|
||||
tik_hdr *GetTikHdr(u8 *tik);
|
||||
bool GetTikTitleKey(u8 *titleKey, tik_hdr *hdr, keys_struct *keys);
|
||||
@@ -0,0 +1,249 @@
|
||||
#include "lib.h"
|
||||
#include "ncch_read.h"
|
||||
#include "titleid.h"
|
||||
|
||||
const u16 DEFAULT_CATEGORY = PROGRAM_ID_CATEGORY_APPLICATION;
|
||||
const u32 DEFAULT_UNIQUE_ID = 0xff3ff;
|
||||
|
||||
void SetPIDType(u16 *type);
|
||||
int SetPIDCategoryFromName(u16 *cat, char *CategoryStr);
|
||||
int SetPIDCategoryFromFlags(u16 *cat, char **CategoryFlags, u32 FlagNum);
|
||||
int SetPIDCategoryFromFlag(u16 *cat, u16 flag, char *flagName);
|
||||
u32 SetPIDUniqueId(char *UniqueIdStr);
|
||||
int SetTitleVariation(u8 *var, u16 cat, rsf_settings *rsf);
|
||||
|
||||
u64 ConvertTwlIdToCtrId(u64 pgid)
|
||||
{
|
||||
return 0x0004800000000000 | (pgid & 0x00007FFFFFFFFFFF);
|
||||
}
|
||||
|
||||
u16 GetTidCategory(u64 titleId)
|
||||
{
|
||||
return (titleId>>32) & MAX_U16;
|
||||
}
|
||||
|
||||
u32 GetTidUniqueId(u64 titleId)
|
||||
{
|
||||
return (titleId>>8) & 0xFFFFFF;
|
||||
}
|
||||
|
||||
int GetProgramID(u64 *dest, rsf_settings *rsf, bool IsForExheader)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 uniqueId;
|
||||
u16 type,category;
|
||||
u8 variation;
|
||||
|
||||
if(rsf->TitleInfo.Category && rsf->TitleInfo.CategoryFlags){
|
||||
fprintf(stderr,"[ID ERROR] Can not set \"Category\" and \"CategoryFlags\" at the same time.\n");
|
||||
return PID_BAD_RSF_SET;
|
||||
}
|
||||
|
||||
// Getting Type
|
||||
SetPIDType(&type);
|
||||
|
||||
// Getting Category
|
||||
if(IsForExheader && rsf->TitleInfo.TargetCategory)
|
||||
ret = SetPIDCategoryFromName(&category,rsf->TitleInfo.TargetCategory);
|
||||
else if (rsf->TitleInfo.Category)
|
||||
ret = SetPIDCategoryFromName(&category, rsf->TitleInfo.Category);
|
||||
else if (rsf->TitleInfo.CategoryFlags)
|
||||
ret = SetPIDCategoryFromFlags(&category, rsf->TitleInfo.CategoryFlags, rsf->TitleInfo.CategoryFlagsNum);
|
||||
else
|
||||
category = DEFAULT_CATEGORY;
|
||||
|
||||
if(ret == PID_INVALID_CATEGORY) // Error occured
|
||||
return PID_BAD_RSF_SET;
|
||||
|
||||
// Getting UniqueId
|
||||
if(rsf->TitleInfo.UniqueId)
|
||||
GetUniqueID(&uniqueId,rsf);
|
||||
else
|
||||
uniqueId = DEFAULT_UNIQUE_ID;
|
||||
|
||||
if(uniqueId & 0xFFF00000u){
|
||||
fprintf(stderr,"[ID ERROR] Unique ID is out of range.\n");
|
||||
return PID_BAD_RSF_SET;
|
||||
}
|
||||
|
||||
// Getting Variation
|
||||
if(SetTitleVariation(&variation,category,rsf) == PID_INVALID_VARIATION)
|
||||
return PID_BAD_RSF_SET;
|
||||
|
||||
u64 programId = 0;
|
||||
programId |= (u64)variation<<0;
|
||||
programId |= (u64)uniqueId<<8;
|
||||
programId |= (u64)category<<32;
|
||||
programId |= (u64)type<<48;
|
||||
|
||||
*dest = programId;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetPIDType(u16 *type)
|
||||
{
|
||||
*type = 0x0004;
|
||||
}
|
||||
|
||||
int GetUniqueID(u32 *uid, rsf_settings *rsf)
|
||||
{
|
||||
if(rsf->TitleInfo.UniqueId) *uid = 0xffffff & SetPIDUniqueId(rsf->TitleInfo.UniqueId);
|
||||
else{
|
||||
fprintf(stderr,"[ID ERROR] ParameterNotFound: \"TitleInfo/UniqueId\"\n");
|
||||
return PID_BAD_RSF_SET;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetPIDCategoryFromName(u16 *cat, char *CategoryStr)
|
||||
{
|
||||
if(strcmp(CategoryStr,"Application") == 0) *cat = PROGRAM_ID_CATEGORY_APPLICATION;
|
||||
else if(strcmp(CategoryStr,"SystemApplication") == 0) *cat = PROGRAM_ID_CATEGORY_SYSTEM_APPLICATION;
|
||||
else if(strcmp(CategoryStr,"Applet") == 0) *cat = PROGRAM_ID_CATEGORY_APPLET;
|
||||
else if(strcmp(CategoryStr,"Firmware") == 0) *cat = PROGRAM_ID_CATEGORY_FIRMWARE;
|
||||
else if(strcmp(CategoryStr,"Base") == 0) *cat = PROGRAM_ID_CATEGORY_BASE;
|
||||
else if(strcmp(CategoryStr,"DlpChild") == 0) *cat = PROGRAM_ID_CATEGORY_DLP_CHILD;
|
||||
else if(strcmp(CategoryStr,"Demo") == 0) *cat = PROGRAM_ID_CATEGORY_DEMO;
|
||||
else if(strcmp(CategoryStr,"Contents") == 0) *cat = PROGRAM_ID_CATEGORY_CONTENTS;
|
||||
else if(strcmp(CategoryStr,"SystemContents") == 0) *cat = PROGRAM_ID_CATEGORY_SYSTEM_CONTENT;
|
||||
else if(strcmp(CategoryStr,"SharedContents") == 0) *cat = PROGRAM_ID_CATEGORY_SHARED_CONTENT;
|
||||
else if(strcmp(CategoryStr,"AddOnContents") == 0) *cat = PROGRAM_ID_CATEGORY_ADD_ON_CONTENTS;
|
||||
else if(strcmp(CategoryStr,"Patch") == 0) *cat = PROGRAM_ID_CATEGORY_PATCH;
|
||||
else if(strcmp(CategoryStr,"AutoUpdateContents") == 0) *cat = PROGRAM_ID_CATEGORY_AUTO_UPDATE_CONTENT;
|
||||
else {
|
||||
fprintf(stderr,"[ID ERROR] Invalid Category: \"%s\"\n",CategoryStr);
|
||||
return PID_INVALID_CATEGORY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetPIDCategoryFromFlags(u16 *cat, char **CategoryFlags, u32 FlagNum)
|
||||
{
|
||||
int ret = 0;
|
||||
for(u32 i = 0; i < FlagNum; i++){
|
||||
if(strcmp(CategoryFlags[i],"Normal") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_NORMAL,"Normal");
|
||||
else if(strcmp(CategoryFlags[i],"DlpChild") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_DLP_CHILD,"DlpChild");
|
||||
else if(strcmp(CategoryFlags[i],"Demo") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_DEMO,"Demo");
|
||||
else if(strcmp(CategoryFlags[i],"Contents") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_CONTENTS,"Contents");
|
||||
else if(strcmp(CategoryFlags[i],"AddOnContents") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_ADD_ON_CONTENTS,"AddOnContents");
|
||||
else if(strcmp(CategoryFlags[i],"Patch") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_PATCH,"Patch");
|
||||
else if(strcmp(CategoryFlags[i],"CannotExecution") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_CANNOT_EXECUTION,"CannotExecution");
|
||||
else if(strcmp(CategoryFlags[i],"System") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_SYSTEM,"System");
|
||||
else if(strcmp(CategoryFlags[i],"RequireBatchUpdate") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_REQUIRE_BATCH_UPDATE,"RequireBatchUpdate");
|
||||
else if(strcmp(CategoryFlags[i],"NotRequireUserApproval") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_USER_APPROVAL,"NotRequireUserApproval");
|
||||
else if(strcmp(CategoryFlags[i],"NotRequireRightForMount") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_RIGHT_FOR_MOUNT,"NotRequireRightForMount");
|
||||
else if(strcmp(CategoryFlags[i],"CanSkipConvertJumpId") == 0)
|
||||
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_CAN_SKIP_CONVERT_JUMP_ID,"CanSkipConvertJumpId");
|
||||
|
||||
|
||||
else {
|
||||
fprintf(stderr,"[ID ERROR] Invalid CategoryFlag: \"%s\"\n",CategoryFlags[i]);
|
||||
return PID_INVALID_CATEGORY;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SetPIDCategoryFromFlag(u16 *cat, u16 flag, char *flagName)
|
||||
{
|
||||
if(!flag) return 0;
|
||||
if((*cat & flag) == flag){
|
||||
fprintf(stderr,"[ID ERROR] Failed to set \"%s\" for category. CategoryFlag was already set.\n",flagName);
|
||||
return PID_INVALID_CATEGORY;
|
||||
}
|
||||
*cat |= flag;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 SetPIDUniqueId(char *UniqueIdStr)
|
||||
{
|
||||
return 0xffffff & strtoull(UniqueIdStr,NULL,0);
|
||||
}
|
||||
|
||||
int SetTitleVariation(u8 *var, u16 cat, rsf_settings *rsf)
|
||||
{
|
||||
if(IsDemo(cat)){
|
||||
if(rsf->TitleInfo.DemoIndex){
|
||||
u8 DemoIndex = 0xff & strtol(rsf->TitleInfo.DemoIndex,NULL,10);
|
||||
if(DemoIndex == 0){
|
||||
fprintf(stderr,"[ID ERROR] Invalid demo index \"%d\"\n",DemoIndex);
|
||||
return PID_INVALID_VARIATION;
|
||||
}
|
||||
*var = DemoIndex;
|
||||
}
|
||||
else{
|
||||
fprintf(stderr,"[ID ERROR] ParameterNotFound: \"TitleInfo/DemoIndex\"\n");
|
||||
return PID_INVALID_VARIATION;
|
||||
}
|
||||
}
|
||||
|
||||
else if(IsDlpChild(cat)){
|
||||
if(rsf->TitleInfo.ChildIndex)
|
||||
*var = 0xff & strtol(rsf->TitleInfo.ChildIndex,NULL,10);
|
||||
else
|
||||
*var = 0;
|
||||
}
|
||||
else if(IsAddOnContent(cat)){
|
||||
if(rsf->TitleInfo.Variation) // Might Rename to DataTitleIndex
|
||||
*var = 0xff & strtol(rsf->TitleInfo.Variation,NULL,10);
|
||||
else
|
||||
*var = 0;
|
||||
}
|
||||
else if(IsContents(cat)){
|
||||
if(rsf->TitleInfo.ContentsIndex)
|
||||
*var = 0xff & strtol(rsf->TitleInfo.ContentsIndex,NULL,10);
|
||||
else
|
||||
*var = 0;
|
||||
}
|
||||
else{
|
||||
if(rsf->TitleInfo.Version)
|
||||
*var = 0xff & strtol(rsf->TitleInfo.Version,NULL,10);
|
||||
else
|
||||
*var = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsDemo(u16 Category)
|
||||
{
|
||||
return Category == PROGRAM_ID_CATEGORY_DEMO;
|
||||
}
|
||||
|
||||
bool IsSystem(u16 Category)
|
||||
{
|
||||
return (Category & PROGRAM_ID_CATEGORY_FLAG_SYSTEM) == PROGRAM_ID_CATEGORY_FLAG_SYSTEM;
|
||||
}
|
||||
|
||||
bool IsDlpChild(u16 Category)
|
||||
{
|
||||
return Category == PROGRAM_ID_CATEGORY_DLP_CHILD;
|
||||
}
|
||||
|
||||
bool IsPatch(u16 Category)
|
||||
{
|
||||
return Category == PROGRAM_ID_CATEGORY_PATCH;
|
||||
}
|
||||
|
||||
bool IsContents(u16 Category)
|
||||
{
|
||||
return (Category & PROGRAM_ID_CATEGORY_FLAG_CONTENTS) == PROGRAM_ID_CATEGORY_FLAG_CONTENTS;
|
||||
}
|
||||
|
||||
bool IsAddOnContent(u16 Category)
|
||||
{
|
||||
return Category == PROGRAM_ID_CATEGORY_ADD_ON_CONTENTS;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PID_BAD_RSF_SET = -1,
|
||||
PID_INVALID_CATEGORY = -2,
|
||||
PID_INVALID_UNIQUE_ID = -3,
|
||||
PID_INVALID_VARIATION = -4,
|
||||
} Pid_Errors;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROGRAM_ID_CATEGORY_FLAG_NORMAL = 0x0000,
|
||||
PROGRAM_ID_CATEGORY_FLAG_DLP_CHILD = 0x0001,
|
||||
PROGRAM_ID_CATEGORY_FLAG_DEMO = 0x0002,
|
||||
PROGRAM_ID_CATEGORY_FLAG_CONTENTS = 0x0003,
|
||||
PROGRAM_ID_CATEGORY_FLAG_ADD_ON_CONTENTS = 0x0004,
|
||||
PROGRAM_ID_CATEGORY_FLAG_PATCH = 0x0006,
|
||||
PROGRAM_ID_CATEGORY_FLAG_CANNOT_EXECUTION = 0x0008,
|
||||
PROGRAM_ID_CATEGORY_FLAG_SYSTEM = 0x0010,
|
||||
PROGRAM_ID_CATEGORY_FLAG_REQUIRE_BATCH_UPDATE = 0x0020,
|
||||
PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_USER_APPROVAL = 0x0040,
|
||||
PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_RIGHT_FOR_MOUNT = 0x0080,
|
||||
PROGRAM_ID_CATEGORY_FLAG_CAN_SKIP_CONVERT_JUMP_ID = 0x0100,
|
||||
PROGRAM_ID_CATEGORY_FLAG_TWL = 0x8000,
|
||||
} ProgramIdCategoryFlag;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROGRAM_ID_CATEGORY_APPLICATION = ( PROGRAM_ID_CATEGORY_FLAG_NORMAL ),
|
||||
|
||||
PROGRAM_ID_CATEGORY_DLP_CHILD = ( PROGRAM_ID_CATEGORY_FLAG_DLP_CHILD ),
|
||||
|
||||
PROGRAM_ID_CATEGORY_DEMO = ( PROGRAM_ID_CATEGORY_FLAG_DEMO ),
|
||||
|
||||
PROGRAM_ID_CATEGORY_CONTENTS = ( PROGRAM_ID_CATEGORY_FLAG_CONTENTS ),
|
||||
|
||||
PROGRAM_ID_CATEGORY_PATCH = ( PROGRAM_ID_CATEGORY_FLAG_CANNOT_EXECUTION
|
||||
| PROGRAM_ID_CATEGORY_FLAG_PATCH),
|
||||
|
||||
PROGRAM_ID_CATEGORY_ADD_ON_CONTENTS = ( PROGRAM_ID_CATEGORY_FLAG_ADD_ON_CONTENTS
|
||||
| PROGRAM_ID_CATEGORY_FLAG_CANNOT_EXECUTION
|
||||
| PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_RIGHT_FOR_MOUNT ),
|
||||
|
||||
PROGRAM_ID_CATEGORY_FIRMWARE = ( PROGRAM_ID_CATEGORY_FLAG_NORMAL
|
||||
| PROGRAM_ID_CATEGORY_FLAG_CANNOT_EXECUTION
|
||||
| PROGRAM_ID_CATEGORY_FLAG_SYSTEM
|
||||
| PROGRAM_ID_CATEGORY_FLAG_REQUIRE_BATCH_UPDATE
|
||||
| PROGRAM_ID_CATEGORY_FLAG_CAN_SKIP_CONVERT_JUMP_ID ),
|
||||
|
||||
|
||||
PROGRAM_ID_CATEGORY_BASE = ( PROGRAM_ID_CATEGORY_FLAG_NORMAL
|
||||
| PROGRAM_ID_CATEGORY_FLAG_SYSTEM
|
||||
| PROGRAM_ID_CATEGORY_FLAG_REQUIRE_BATCH_UPDATE
|
||||
| PROGRAM_ID_CATEGORY_FLAG_CAN_SKIP_CONVERT_JUMP_ID ),
|
||||
|
||||
|
||||
PROGRAM_ID_CATEGORY_APPLET = ( PROGRAM_ID_CATEGORY_FLAG_NORMAL
|
||||
| PROGRAM_ID_CATEGORY_FLAG_SYSTEM
|
||||
| PROGRAM_ID_CATEGORY_FLAG_REQUIRE_BATCH_UPDATE ),
|
||||
|
||||
|
||||
PROGRAM_ID_CATEGORY_SYSTEM_APPLICATION = ( PROGRAM_ID_CATEGORY_FLAG_NORMAL
|
||||
| PROGRAM_ID_CATEGORY_FLAG_SYSTEM ),
|
||||
|
||||
|
||||
PROGRAM_ID_CATEGORY_SYSTEM_CONTENT = ( PROGRAM_ID_CATEGORY_FLAG_CONTENTS
|
||||
| PROGRAM_ID_CATEGORY_FLAG_CANNOT_EXECUTION
|
||||
| PROGRAM_ID_CATEGORY_FLAG_SYSTEM ),
|
||||
|
||||
|
||||
PROGRAM_ID_CATEGORY_SHARED_CONTENT = ( PROGRAM_ID_CATEGORY_FLAG_CONTENTS
|
||||
| PROGRAM_ID_CATEGORY_FLAG_CANNOT_EXECUTION
|
||||
| PROGRAM_ID_CATEGORY_FLAG_SYSTEM
|
||||
| PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_RIGHT_FOR_MOUNT ),
|
||||
|
||||
|
||||
PROGRAM_ID_CATEGORY_AUTO_UPDATE_CONTENT = ( PROGRAM_ID_CATEGORY_FLAG_CONTENTS
|
||||
| PROGRAM_ID_CATEGORY_FLAG_CANNOT_EXECUTION
|
||||
| PROGRAM_ID_CATEGORY_FLAG_SYSTEM
|
||||
| PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_USER_APPROVAL
|
||||
| PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_RIGHT_FOR_MOUNT ),
|
||||
|
||||
} ProgramIdCategory;
|
||||
|
||||
u64 ConvertTwlIdToCtrId(u64 pgid);
|
||||
|
||||
int GetProgramID(u64 *dest, rsf_settings *rsf, bool IsForExheader);
|
||||
int GetUniqueID(u32 *dest, rsf_settings *rsf);
|
||||
|
||||
u16 GetTidCategory(u64 titleId);
|
||||
u32 GetTidUniqueId(u64 titleId);
|
||||
|
||||
bool IsDemo(u16 Category);
|
||||
bool IsSystem(u16 Category);
|
||||
bool IsDlpChild(u16 Category);
|
||||
bool IsPatch(u16 Category);
|
||||
bool IsContents(u16 Category);
|
||||
bool IsAddOnContent(u16 Category);
|
||||
@@ -0,0 +1,195 @@
|
||||
#include "lib.h"
|
||||
#include "cia_build.h"
|
||||
#include "tmd_build.h"
|
||||
|
||||
// Private Prototypes
|
||||
int SetupTMDBuffer(buffer_struct *tik);
|
||||
int SetupTMDHeader(tmd_hdr *hdr, tmd_content_info_record *info_record, cia_settings *ciaset);
|
||||
int SignTMDHeader(tmd_hdr *hdr, tmd_signature *sig, keys_struct *keys);
|
||||
int SetupTMDInfoRecord(tmd_content_info_record *info_record, u8 *content_record, u16 ContentCount);
|
||||
int SetupTMDContentRecord(u8 *content_record, cia_settings *ciaset);
|
||||
|
||||
u32 PredictTMDSize(u16 ContentCount)
|
||||
{
|
||||
return sizeof(tmd_signature) + sizeof(tmd_hdr) + sizeof(tmd_content_info_record)*64 + sizeof(tmd_content_chunk)*ContentCount;
|
||||
}
|
||||
|
||||
int BuildTMD(cia_settings *ciaset)
|
||||
{
|
||||
int result = 0;
|
||||
ciaset->ciaSections.tmd.size = PredictTMDSize(ciaset->content.count);
|
||||
result = SetupTMDBuffer(&ciaset->ciaSections.tmd);
|
||||
if(result) return result;
|
||||
|
||||
// Setting TMD Struct Ptrs
|
||||
tmd_signature *sig = (tmd_signature*)ciaset->ciaSections.tmd.buffer;
|
||||
tmd_hdr *hdr = (tmd_hdr*)(ciaset->ciaSections.tmd.buffer+sizeof(tmd_signature));
|
||||
tmd_content_info_record *info_record = (tmd_content_info_record*)(ciaset->ciaSections.tmd.buffer+sizeof(tmd_signature)+sizeof(tmd_hdr));
|
||||
u8 *content_record = (u8*)(ciaset->ciaSections.tmd.buffer+sizeof(tmd_signature)+sizeof(tmd_hdr)+sizeof(tmd_content_info_record)*64);
|
||||
|
||||
|
||||
SetupTMDContentRecord(content_record,ciaset);
|
||||
SetupTMDInfoRecord(info_record,content_record,ciaset->content.count);
|
||||
result = SetupTMDHeader(hdr,info_record,ciaset);
|
||||
if(result) return result;
|
||||
result = SignTMDHeader(hdr,sig,ciaset->keys);
|
||||
return result;
|
||||
}
|
||||
|
||||
int SetupTMDBuffer(buffer_struct *tmd)
|
||||
{
|
||||
tmd->buffer = calloc(1,tmd->size);
|
||||
if(!tmd->buffer) {
|
||||
fprintf(stderr,"[TMD ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetupTMDHeader(tmd_hdr *hdr, tmd_content_info_record *info_record, cia_settings *ciaset)
|
||||
{
|
||||
clrmem(hdr,sizeof(tmd_hdr));
|
||||
|
||||
memcpy(hdr->issuer,ciaset->tmd.issuer,0x40);
|
||||
hdr->formatVersion = ciaset->tmd.formatVersion;
|
||||
hdr->caCrlVersion = ciaset->cert.caCrlVersion;
|
||||
hdr->signerCrlVersion = ciaset->cert.signerCrlVersion;
|
||||
u64_to_u8(hdr->titleID,ciaset->common.titleId,BE);
|
||||
u32_to_u8(hdr->titleType,ciaset->tmd.titleType,BE);
|
||||
u32_to_u8(hdr->savedataSize,ciaset->tmd.savedataSize,LE);
|
||||
u32_to_u8(hdr->privSavedataSize,ciaset->tmd.privSavedataSize,LE);
|
||||
hdr->twlFlag = ciaset->tmd.twlFlag;
|
||||
u32_to_u8(hdr->accessRights,ciaset->tmd.accessRights,BE);
|
||||
u16_to_u8(hdr->titleVersion,ciaset->tmd.version,BE);
|
||||
u16_to_u8(hdr->contentCount,ciaset->content.count,BE);
|
||||
ShaCalc(info_record,sizeof(tmd_content_info_record)*64,hdr->infoRecordHash,CTR_SHA_256);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SignTMDHeader(tmd_hdr *hdr, tmd_signature *sig, keys_struct *keys)
|
||||
{
|
||||
clrmem(sig,sizeof(tmd_signature));
|
||||
u32_to_u8(sig->sigType,RSA_2048_SHA256,BE);
|
||||
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.cp) == false)
|
||||
{
|
||||
printf("[TMD WARNING] Failed to sign header (key was incomplete)\n");
|
||||
memset(sig->data, 0xFF, 0x100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rsa_ret = RsaSignVerify((u8*)hdr, sizeof(tmd_hdr), sig->data, keys->rsa.cp.pub, keys->rsa.cp.pvt, RSA_2048_SHA256, CTR_RSA_SIGN);
|
||||
if (rsa_ret != 0)
|
||||
{
|
||||
printf("[TMD WARNING] Failed to sign header (mbedtls error = -0x%x)\n", -rsa_ret);
|
||||
memset(sig->data, 0xFF, 0x100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetupTMDInfoRecord(tmd_content_info_record *info_record, u8 *content_record, u16 ContentCount)
|
||||
{
|
||||
clrmem(info_record,sizeof(tmd_content_info_record)*0x40);
|
||||
u16_to_u8(info_record->contentIndexOffset,0x0,BE);
|
||||
u16_to_u8(info_record->contentCommandCount,ContentCount,BE);
|
||||
ShaCalc(content_record,sizeof(tmd_content_chunk)*ContentCount,info_record->contentChunkHash,CTR_SHA_256);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetupTMDContentRecord(u8 *content_record, cia_settings *ciaset)
|
||||
{
|
||||
for(int i = 0; i < ciaset->content.count; i++){
|
||||
tmd_content_chunk *ptr = (tmd_content_chunk*)(content_record+sizeof(tmd_content_chunk)*i);
|
||||
u32_to_u8(ptr->id,ciaset->content.id[i],BE);
|
||||
u16_to_u8(ptr->index,ciaset->content.index[i],BE);
|
||||
u16_to_u8(ptr->flags,ciaset->content.flags[i],BE);
|
||||
u64_to_u8(ptr->size,ciaset->content.size[i],BE);
|
||||
memcpy(ptr->hash,ciaset->content.hash[i],0x20);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmd_hdr *GetTmdHdr(u8 *tmd)
|
||||
{
|
||||
u32 sigType = u8_to_u32(tmd,BE);
|
||||
|
||||
switch(sigType){
|
||||
case(RSA_4096_SHA1):
|
||||
case(RSA_4096_SHA256):
|
||||
return (tmd_hdr*)(tmd+0x240);
|
||||
case(RSA_2048_SHA1):
|
||||
case(RSA_2048_SHA256):
|
||||
return (tmd_hdr*)(tmd+0x140);
|
||||
case(ECC_SHA1):
|
||||
case(ECC_SHA256):
|
||||
return (tmd_hdr*)(tmd+0x7C);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmd_content_chunk* GetTmdContentInfo(u8 *tmd)
|
||||
{
|
||||
tmd_hdr *hdr = GetTmdHdr(tmd);
|
||||
if(!hdr)
|
||||
return NULL;
|
||||
|
||||
return (tmd_content_chunk*)((u8*)hdr + sizeof(tmd_hdr) + (sizeof(tmd_content_info_record)*64));
|
||||
}
|
||||
|
||||
u64 GetTmdTitleId(tmd_hdr *hdr)
|
||||
{
|
||||
return u8_to_u64(hdr->titleID,BE);
|
||||
}
|
||||
|
||||
u32 GetTmdSaveSize(tmd_hdr *hdr)
|
||||
{
|
||||
return u8_to_u32(hdr->savedataSize,LE);
|
||||
}
|
||||
|
||||
u16 GetTmdContentCount(tmd_hdr *hdr)
|
||||
{
|
||||
return u8_to_u16(hdr->contentCount,BE);
|
||||
}
|
||||
|
||||
u16 GetTmdVersion(tmd_hdr *hdr)
|
||||
{
|
||||
return u8_to_u16(hdr->titleVersion,BE);
|
||||
}
|
||||
|
||||
u32 GetTmdContentId(tmd_content_chunk info)
|
||||
{
|
||||
return u8_to_u32(info.id,BE);
|
||||
}
|
||||
|
||||
u16 GetTmdContentIndex(tmd_content_chunk info)
|
||||
{
|
||||
return u8_to_u16(info.index,BE);
|
||||
}
|
||||
|
||||
u16 GetTmdContentFlags(tmd_content_chunk info)
|
||||
{
|
||||
return u8_to_u16(info.flags,BE);
|
||||
}
|
||||
|
||||
u64 GetTmdContentSize(tmd_content_chunk info)
|
||||
{
|
||||
return u8_to_u64(info.size,BE);
|
||||
}
|
||||
|
||||
u8* GetTmdContentHash(tmd_content_chunk *info)
|
||||
{
|
||||
return (u8*)info->hash;
|
||||
}
|
||||
|
||||
bool IsTmdContentEncrypted(tmd_content_chunk info)
|
||||
{
|
||||
return (GetTmdContentFlags(info) & content_Encrypted) == content_Encrypted;
|
||||
}
|
||||
|
||||
bool ValidateTmdContent(u8 *data, tmd_content_chunk info)
|
||||
{
|
||||
return VerifySha256(data, GetTmdContentSize(info), GetTmdContentHash(&info));
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TYPE_CTR = 0x40,
|
||||
TYPE_DATA = 0x8
|
||||
} tmd_title_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
content_Encrypted = 0x0001,
|
||||
content_Optional = 0x4000,
|
||||
content_Shared = 0x8000
|
||||
} tmd_content_types;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 id[4];
|
||||
u8 index[2];
|
||||
u8 flags[2];
|
||||
u8 size[8];
|
||||
u8 hash[0x20]; // SHA 256
|
||||
} tmd_content_chunk;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 contentIndexOffset[2];
|
||||
u8 contentCommandCount[2];
|
||||
u8 contentChunkHash[0x20]; // SHA 256
|
||||
} tmd_content_info_record;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 sigType[4];
|
||||
u8 data[0x100];
|
||||
u8 padding[0x3C];
|
||||
} tmd_signature;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 issuer[0x40];
|
||||
u8 formatVersion;
|
||||
u8 caCrlVersion;
|
||||
u8 signerCrlVersion;
|
||||
u8 padding0;
|
||||
u8 systemVersion[8];
|
||||
u8 titleID[8];
|
||||
u8 titleType[4];
|
||||
u8 groupID[2];
|
||||
u8 savedataSize[4];
|
||||
u8 privSavedataSize[4]; // Zero for CXI Content0
|
||||
u8 padding1[4];
|
||||
u8 twlFlag; // Zero for CXI Content0
|
||||
u8 padding2[0x31];
|
||||
u8 accessRights[4];
|
||||
u8 titleVersion[2];
|
||||
u8 contentCount[2];
|
||||
u8 bootContent[2];
|
||||
u8 padding3[2];
|
||||
u8 infoRecordHash[0x20]; // SHA-256
|
||||
} tmd_hdr;
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "tmd.h"
|
||||
|
||||
// Prototypes
|
||||
u32 PredictTMDSize(u16 ContentCount);
|
||||
int BuildTMD(cia_settings *ciaset);
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "tmd.h"
|
||||
|
||||
// Read TMD
|
||||
tmd_hdr *GetTmdHdr(u8 *tmd);
|
||||
tmd_content_chunk* GetTmdContentInfo(u8 *tmd);
|
||||
u64 GetTmdTitleId(tmd_hdr *hdr);
|
||||
u32 GetTmdSaveSize(tmd_hdr *hdr);
|
||||
u16 GetTmdContentCount(tmd_hdr *hdr);
|
||||
u16 GetTmdVersion(tmd_hdr *hdr);
|
||||
|
||||
u32 GetTmdContentId(tmd_content_chunk info);
|
||||
u16 GetTmdContentIndex(tmd_content_chunk info);
|
||||
u16 GetTmdContentFlags(tmd_content_chunk info);
|
||||
u64 GetTmdContentSize(tmd_content_chunk info);
|
||||
u8* GetTmdContentHash(tmd_content_chunk info);
|
||||
|
||||
bool IsTmdContentEncrypted(tmd_content_chunk info);
|
||||
bool ValidateTmdContent(u8 *data, tmd_content_chunk info);
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
//Bools
|
||||
typedef enum
|
||||
{
|
||||
Good,
|
||||
Fail
|
||||
} return_basic;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEM_ERROR = -1,
|
||||
FAILED_TO_OPEN_FILE = -2,
|
||||
FAILED_TO_IMPORT_FILE = -3,
|
||||
FAILED_TO_CREATE_OUTFILE = -4,
|
||||
} global_errors;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BE = 0,
|
||||
LE = 1
|
||||
} endianness_flag;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KB = 1024,
|
||||
MB = 1048576,
|
||||
GB = 1073741824
|
||||
} file_unit_size;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MAX_U8 = 0xff,
|
||||
MAX_U16 = 0xffff,
|
||||
MAX_U32 = 0xffffffff,
|
||||
MAX_U64 = 0xffffffffffffffff,
|
||||
} data_type_max;
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,308 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CCI_MAX_CONTENT = 8,
|
||||
CIA_MAX_CONTENT = MAX_U16,
|
||||
} content_limits;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VER_MAJOR,
|
||||
VER_MINOR,
|
||||
VER_MICRO
|
||||
} title_ver_index;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VER_MAX = 65535,
|
||||
VER_MAJOR_MAX = 63,
|
||||
VER_MINOR_MAX = 63,
|
||||
VER_MICRO_MAX = 15,
|
||||
VER_DVER_MAX = 4095,
|
||||
} title_ver_max;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CVER_DTYPE_TMD,
|
||||
CVER_DTYPE_CIA,
|
||||
} cver_data_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USR_PTR_PASS_FAIL = -1,
|
||||
USR_HELP = -2,
|
||||
USR_ARG_REQ_PARAM = -3,
|
||||
USR_UNK_ARG = -4,
|
||||
USR_BAD_ARG = -5,
|
||||
USR_MEM_ERROR = -6,
|
||||
} user_settings_errors;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
infile_none,
|
||||
infile_ncch,
|
||||
infile_ncsd,
|
||||
infile_srl,
|
||||
infile_cia,
|
||||
} infile_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
format_not_set,
|
||||
CXI,
|
||||
CFA,
|
||||
CCI,
|
||||
CIA,
|
||||
NCCH
|
||||
} output_format;
|
||||
|
||||
static const char output_extention[5][5] = {".cxi",".cfa",".cci",".cia",".app"};
|
||||
|
||||
/* This does not follow style, so the rsf string names match the variables where they're stored */
|
||||
typedef struct
|
||||
{
|
||||
struct{
|
||||
// Booleans
|
||||
bool MediaFootPadding;
|
||||
bool AllowUnalignedSection;
|
||||
bool EnableCrypt;
|
||||
bool EnableCompress;
|
||||
bool FreeProductCode;
|
||||
bool UseOnSD;
|
||||
} Option;
|
||||
|
||||
struct{
|
||||
// Booleans
|
||||
bool DisableDebug;
|
||||
bool EnableForceDebug;
|
||||
bool CanWriteSharedPage;
|
||||
bool CanUsePrivilegedPriority;
|
||||
bool CanUseNonAlphabetAndNumber;
|
||||
bool PermitMainFunctionArgument;
|
||||
bool CanShareDeviceMemory;
|
||||
bool UseOtherVariationSaveData;
|
||||
bool RunnableOnSleep;
|
||||
bool SpecialMemoryArrange;
|
||||
bool CanAccessCore2;
|
||||
bool UseExtSaveData;
|
||||
bool EnableL2Cache;
|
||||
|
||||
// Strings
|
||||
char *IdealProcessor;
|
||||
char *Priority;
|
||||
char *MemoryType;
|
||||
char *SystemMode;
|
||||
char *SystemModeExt;
|
||||
char *CpuSpeed;
|
||||
char *CoreVersion;
|
||||
char *HandleTableSize;
|
||||
char *SystemSaveDataId1;
|
||||
char *SystemSaveDataId2;
|
||||
char *OtherUserSaveDataId1;
|
||||
char *OtherUserSaveDataId2;
|
||||
char *OtherUserSaveDataId3;
|
||||
char *ExtSaveDataId;
|
||||
char *AffinityMask;
|
||||
// Strings From DESC
|
||||
char *DescVersion;
|
||||
char *ResourceLimitCategory;
|
||||
char *ReleaseKernelMajor;
|
||||
char *ReleaseKernelMinor;
|
||||
char *MaxCpu;
|
||||
|
||||
// String Collections
|
||||
u32 MemoryMappingNum;
|
||||
char **MemoryMapping;
|
||||
u32 IORegisterMappingNum;
|
||||
char **IORegisterMapping;
|
||||
u32 FileSystemAccessNum;
|
||||
char **FileSystemAccess;
|
||||
u32 IoAccessControlNum;
|
||||
char **IoAccessControl; //Equiv to Arm9AccessControl
|
||||
u32 InterruptNumbersNum;
|
||||
char **InterruptNumbers;
|
||||
u32 SystemCallAccessNum;
|
||||
char **SystemCallAccess;
|
||||
u32 ServiceAccessControlNum;
|
||||
char **ServiceAccessControl;
|
||||
u32 AccessibleSaveDataIdsNum;
|
||||
char **AccessibleSaveDataIds;
|
||||
} AccessControlInfo;
|
||||
|
||||
struct{
|
||||
// Strings
|
||||
char *AppType;
|
||||
char *StackSize;
|
||||
char *RemasterVersion;
|
||||
char *SaveDataSize;
|
||||
char *JumpId;
|
||||
|
||||
// String Collections
|
||||
u32 DependencyNum;
|
||||
char **Dependency;
|
||||
} SystemControlInfo;
|
||||
|
||||
struct{
|
||||
// Strings
|
||||
char *Title;
|
||||
char *CompanyCode;
|
||||
char *ProductCode;
|
||||
char *ContentType;
|
||||
char *Logo;
|
||||
} BasicInfo;
|
||||
|
||||
struct{
|
||||
// Strings
|
||||
char *RootPath;
|
||||
|
||||
// String Collections
|
||||
u32 DefaultRejectNum;
|
||||
char **DefaultReject;
|
||||
u32 RejectNum;
|
||||
char **Reject;
|
||||
u32 IncludeNum;
|
||||
char **Include;
|
||||
u32 FileNum;
|
||||
char **File;
|
||||
} RomFs;
|
||||
|
||||
struct{
|
||||
// Strings
|
||||
char *Platform;
|
||||
char *Category;
|
||||
char *UniqueId;
|
||||
char *Version;
|
||||
char *ContentsIndex;
|
||||
char *Variation;
|
||||
char *ChildIndex;
|
||||
char *DemoIndex;
|
||||
char *TargetCategory;
|
||||
|
||||
// String Collections
|
||||
u32 CategoryFlagsNum;
|
||||
char **CategoryFlags;
|
||||
} TitleInfo;
|
||||
|
||||
struct{
|
||||
char *WritableAddress;
|
||||
char *CardType;
|
||||
char *CryptoType;
|
||||
char *CardDevice;
|
||||
char *MediaType;
|
||||
char *MediaSize;
|
||||
char *BackupWriteWaitTime;
|
||||
char *SaveCrypto;
|
||||
} CardInfo;
|
||||
|
||||
struct{
|
||||
bool Found;
|
||||
|
||||
char *D;
|
||||
char *P;
|
||||
char *Q;
|
||||
char *DP;
|
||||
char *DQ;
|
||||
char *InverseQ;
|
||||
char *Modulus;
|
||||
char *Exponent;
|
||||
|
||||
char *AccCtlDescSign;
|
||||
char *AccCtlDescBin;
|
||||
} CommonHeaderKey;
|
||||
} rsf_settings;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
} dname_item;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dname_item *items;
|
||||
u32 m_items;
|
||||
u32 u_items;
|
||||
} dname_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct{
|
||||
bool verbose;
|
||||
|
||||
char *rsfPath;
|
||||
bool outFileName_mallocd;
|
||||
char *outFileName;
|
||||
output_format outFormat;
|
||||
|
||||
// Keys
|
||||
keys_struct keys;
|
||||
|
||||
// RSF Imported Settings
|
||||
rsf_settings rsfSet;
|
||||
|
||||
// Content Details
|
||||
char **contentPath;
|
||||
u64 contentSize[CIA_MAX_CONTENT];
|
||||
|
||||
char *workingFilePath;
|
||||
infile_type workingFileType; // Could Be ncch/ncsd/srl/cia.
|
||||
buffer_struct workingFile;
|
||||
} common;
|
||||
|
||||
dname_struct dname; // For RSF value subsitution
|
||||
|
||||
struct{
|
||||
bool buildNcch0;
|
||||
output_format ncchType;
|
||||
char *elfPath;
|
||||
char *iconPath;
|
||||
char *bannerPath;
|
||||
char *logoPath; // override logo specs in RSF
|
||||
|
||||
bool includeExefsLogo; // for <5.x compatibility
|
||||
|
||||
// ncch rebuild settings
|
||||
char *codePath; // uncompressed exefs .code
|
||||
char *exheaderPath; // for .code details
|
||||
char *plainRegionPath; // prebuilt Plain Region
|
||||
char *romfsPath; // Prebuild _cleartext_ romfs binary
|
||||
bool noCodePadding; // do not pad code.bin for sysmodule
|
||||
|
||||
bool useSecCrypto;
|
||||
u8 keyXID;
|
||||
} ncch; // Ncch0 Build
|
||||
|
||||
struct{
|
||||
bool useSDKStockData; // incase we want to use the SDK stock data, for whatever reason.
|
||||
bool dontModifyNcchTitleID;
|
||||
bool closeAlignWritableRegion;
|
||||
|
||||
u8 cverDataType;
|
||||
char *cverDataPath;
|
||||
} cci; // CCI Settings
|
||||
|
||||
struct{
|
||||
bool randomTitleKey;
|
||||
char *titleKey;
|
||||
bool encryptCia;
|
||||
bool DlcContent;
|
||||
bool includeUpdateNcch;
|
||||
|
||||
bool useNormTitleVer;
|
||||
bool useDataTitleVer;
|
||||
bool useFullTitleVer;
|
||||
u16 titleVersion[3];
|
||||
|
||||
u32 deviceId;
|
||||
u32 eshopAccId;
|
||||
|
||||
u64 contentId[CIA_MAX_CONTENT]; // For CIA
|
||||
} cia; // CIA Settings
|
||||
} user_settings;
|
||||
|
||||
// Prototypes
|
||||
|
||||
void init_UserSettings(user_settings *set);
|
||||
void free_UserSettings(user_settings *set);
|
||||
int ParseArgs(int argc, char *argv[], user_settings *usr_settings);
|
||||
@@ -0,0 +1,422 @@
|
||||
#include "lib.h"
|
||||
#include <mbedtls/base64.h>
|
||||
|
||||
#define IO_BLOCKSIZE 5*MB
|
||||
|
||||
// Memory
|
||||
int CopyData(u8 **dest, const u8 *source, u64 size)
|
||||
{
|
||||
if(!*dest){
|
||||
*dest = malloc(size);
|
||||
if(!*dest) return -1;
|
||||
}
|
||||
memcpy(*dest,source,size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rndset(void *ptr, u64 num)
|
||||
{
|
||||
u8 *tmp = (u8*)ptr;
|
||||
for(u64 i = 0; i < num ; i++)
|
||||
tmp[i] = u8GetRand();
|
||||
}
|
||||
|
||||
void clrmem(void *ptr, u64 num)
|
||||
{
|
||||
memset(ptr,0,num);
|
||||
}
|
||||
|
||||
// Misc
|
||||
u64 roundup(u64 value, u64 alignment)
|
||||
{
|
||||
return value + alignment - value % alignment;
|
||||
}
|
||||
|
||||
u64 align(u64 value, u64 alignment)
|
||||
{
|
||||
if(value % alignment != 0)
|
||||
return roundup(value,alignment);
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
u64 min64(u64 a, u64 b)
|
||||
{
|
||||
if(a < b) return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
u64 max64(u64 a, u64 b)
|
||||
{
|
||||
if(a > b) return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
// Strings
|
||||
char* replace_filextention(const char *input, const char *new_ext)
|
||||
{
|
||||
if(input == NULL || new_ext == NULL)
|
||||
return NULL;
|
||||
|
||||
char *new_name;
|
||||
char *ext = strrchr(input, '.');
|
||||
|
||||
// If there is no existing extention, just append new_ext
|
||||
if (!ext) {
|
||||
new_name = calloc(strlen(input) + strlen(new_ext), 1);
|
||||
sprintf(new_name, "%s%s", input, new_ext);
|
||||
}
|
||||
else {
|
||||
u32 size = ext - input;
|
||||
new_name = calloc(size + strlen(new_ext) + 1, 1);
|
||||
strncpy(new_name, input, size);
|
||||
sprintf(new_name, "%s%s", new_name, new_ext);
|
||||
}
|
||||
|
||||
return new_name;
|
||||
}
|
||||
|
||||
void memdump(FILE* fout, const char* prefix, const u8* data, u32 size)
|
||||
{
|
||||
u32 i;
|
||||
u32 prefixlen = strlen(prefix);
|
||||
u32 offs = 0;
|
||||
u32 line = 0;
|
||||
while(size)
|
||||
{
|
||||
u32 max = 32;
|
||||
|
||||
if (max > size)
|
||||
max = size;
|
||||
|
||||
if (line==0)
|
||||
fprintf(fout, "%s", prefix);
|
||||
else
|
||||
fprintf(fout, "%*s", prefixlen, "");
|
||||
|
||||
|
||||
for(i=0; i<max; i++)
|
||||
fprintf(fout, "%02X", data[offs+i]);
|
||||
fprintf(fout, "\n");
|
||||
line++;
|
||||
size -= max;
|
||||
offs += max;
|
||||
}
|
||||
}
|
||||
|
||||
// Base64
|
||||
bool IsValidB64Char(char chr)
|
||||
{
|
||||
return (isalnum(chr) || chr == '+' || chr == '/' || chr == '=');
|
||||
}
|
||||
|
||||
size_t b64_strlen(const char *str)
|
||||
{
|
||||
size_t count = 0;
|
||||
size_t i = 0;
|
||||
while(str[i] != 0x0){
|
||||
if(IsValidB64Char(str[i])) {
|
||||
//printf("Is Valid: %c\n",str[i]);
|
||||
count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void b64_strcpy(char *dst, const char *src)
|
||||
{
|
||||
size_t src_len = strlen(src);
|
||||
size_t j = 0;
|
||||
for(size_t i = 0; i < src_len; i++){
|
||||
if(IsValidB64Char(src[i])){
|
||||
dst[j] = src[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
dst[j] = 0;
|
||||
|
||||
//memdump(stdout,"src: ",(u8*)src,src_len+1);
|
||||
//memdump(stdout,"dst: ",(u8*)dst,j+1);
|
||||
}
|
||||
|
||||
int b64_decode(u8 *dst, const char *src, size_t dst_size)
|
||||
{
|
||||
int ret;
|
||||
size_t size = dst_size;
|
||||
|
||||
ret = mbedtls_base64_decode(dst, size, &size, (const u8*)src, strlen(src));
|
||||
|
||||
if(size != dst_size)
|
||||
ret = MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Pseudo-Random Number Generator
|
||||
void initRand(void)
|
||||
{
|
||||
srand(time(0));
|
||||
}
|
||||
|
||||
u8 u8GetRand(void)
|
||||
{
|
||||
return rand() % 0xff;
|
||||
}
|
||||
|
||||
u16 u16GetRand(void)
|
||||
{
|
||||
return rand() % 0xffff;
|
||||
}
|
||||
|
||||
u32 u32GetRand(void)
|
||||
{
|
||||
return (u32)u16GetRand() | (u32)u16GetRand() << 16;
|
||||
}
|
||||
|
||||
u64 u64GetRand(void)
|
||||
{
|
||||
return (u64)u32GetRand() | (u64)u32GetRand() << 32;
|
||||
}
|
||||
|
||||
//Char IO
|
||||
bool AssertFile(char *filename)
|
||||
{
|
||||
if(filename == NULL)
|
||||
return false;
|
||||
#ifdef _WIN32
|
||||
struct _stat64 st;
|
||||
return _stat64(filename, &st) == 0;
|
||||
#else
|
||||
struct stat st;
|
||||
return stat(filename, &st) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
u64 GetFileSize64(char *filename)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
struct _stat64 st;
|
||||
if( _stat64(filename, &st) != 0)
|
||||
return 0;
|
||||
else
|
||||
return st.st_size;
|
||||
#else
|
||||
struct stat st;
|
||||
if( stat(filename, &st) != 0)
|
||||
return 0;
|
||||
else
|
||||
return st.st_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
int makedir(const char* dir)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _mkdir(dir);
|
||||
#else
|
||||
return mkdir(dir, 0777);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *getcwdir(char *buffer,int maxlen)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _getcwd(buffer,maxlen);
|
||||
#else
|
||||
return getcwd(buffer,maxlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
int TruncateFile64(char *filename, u64 filelen)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE fh;
|
||||
|
||||
LARGE_INTEGER fp;
|
||||
fp.QuadPart = filelen;
|
||||
|
||||
fh = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (fh == INVALID_HANDLE_VALUE) {
|
||||
printf("[!] Invalid File handle\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SetFilePointerEx(fh, fp, NULL, FILE_BEGIN) == 0 || SetEndOfFile(fh) == 0) {
|
||||
printf("[!] Truncate failed\n");
|
||||
CloseHandle(fh);
|
||||
return 1;
|
||||
}
|
||||
|
||||
CloseHandle(fh);
|
||||
return 0;
|
||||
#else
|
||||
return truncate(filename,filelen);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//IO Misc
|
||||
u8* ImportFile(char *file, u64 size)
|
||||
{
|
||||
u64 fsize = GetFileSize64(file);
|
||||
if(size > 0 && size != fsize){
|
||||
fprintf(stderr,"[!] %s has an invalid size (0x%"PRIx64")\n",file, fsize);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8 *data = (u8*)calloc(1,fsize);
|
||||
if(!data){
|
||||
fprintf(stderr,"[!] Not enough memory\n");
|
||||
return NULL;
|
||||
}
|
||||
FILE *fp = fopen(file,"rb");
|
||||
ReadFile64(data, fsize, 0, fp);
|
||||
fclose(fp);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void WriteBuffer(const void *buffer, u64 size, u64 offset, FILE *fp)
|
||||
{
|
||||
const u8* _buffer = (const u8*)buffer;
|
||||
fseek_64(fp,offset);
|
||||
for (; size > IO_BLOCKSIZE; size -= IO_BLOCKSIZE, _buffer += IO_BLOCKSIZE)
|
||||
fwrite(_buffer, IO_BLOCKSIZE, 1, fp);
|
||||
fwrite(_buffer,size,1,fp);
|
||||
}
|
||||
|
||||
void ReadFile64(void *outbuff, u64 size, u64 offset, FILE *fp)
|
||||
{
|
||||
u8* _buffer = (u8*)outbuff;
|
||||
fseek_64(fp, offset);
|
||||
for (; size > IO_BLOCKSIZE; size -= IO_BLOCKSIZE, _buffer += IO_BLOCKSIZE)
|
||||
fread(_buffer, IO_BLOCKSIZE, 1, fp);
|
||||
fread(_buffer, size, 1, fp);
|
||||
}
|
||||
|
||||
int fseek_64(FILE *fp, u64 file_pos)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fpos_t pos = file_pos;
|
||||
return fsetpos(fp,&pos);
|
||||
#else
|
||||
return fseeko(fp,file_pos,SEEK_SET);
|
||||
#endif
|
||||
}
|
||||
|
||||
//Data Size conversion
|
||||
u16 u8_to_u16(const u8 *value, u8 endianness)
|
||||
{
|
||||
u16 new_value = 0;
|
||||
switch(endianness){
|
||||
case(BE): new_value = (value[1]<<0) | (value[0]<<8); break;
|
||||
case(LE): new_value = (value[0]<<0) | (value[1]<<8); break;
|
||||
}
|
||||
return new_value;
|
||||
}
|
||||
|
||||
u32 u8_to_u32(const u8 *value, u8 endianness)
|
||||
{
|
||||
u32 new_value = 0;
|
||||
switch(endianness){
|
||||
case(BE): new_value = (value[3]<<0) | (value[2]<<8) | (value[1]<<16) | (value[0]<<24); break;
|
||||
case(LE): new_value = (value[0]<<0) | (value[1]<<8) | (value[2]<<16) | (value[3]<<24); break;
|
||||
}
|
||||
return new_value;
|
||||
}
|
||||
|
||||
|
||||
u64 u8_to_u64(const u8 *value, u8 endianness)
|
||||
{
|
||||
u64 ret = 0;
|
||||
switch(endianness){
|
||||
case(BE):
|
||||
ret |= (u64)value[7]<<0;
|
||||
ret |= (u64)value[6]<<8;
|
||||
ret |= (u64)value[5]<<16;
|
||||
ret |= (u64)value[4]<<24;
|
||||
ret |= (u64)value[3]<<32;
|
||||
ret |= (u64)value[2]<<40;
|
||||
ret |= (u64)value[1]<<48;
|
||||
ret |= (u64)value[0]<<56;
|
||||
break;
|
||||
//return (value[7]<<0) | (value[6]<<8) | (value[5]<<16) | (value[4]<<24) | (value[3]<<32) | (value[2]<<40) | (value[1]<<48) | (value[0]<<56);
|
||||
case(LE):
|
||||
ret |= (u64)value[0]<<0;
|
||||
ret |= (u64)value[1]<<8;
|
||||
ret |= (u64)value[2]<<16;
|
||||
ret |= (u64)value[3]<<24;
|
||||
ret |= (u64)value[4]<<32;
|
||||
ret |= (u64)value[5]<<40;
|
||||
ret |= (u64)value[6]<<48;
|
||||
ret |= (u64)value[7]<<56;
|
||||
break;
|
||||
//return (value[0]<<0) | (value[1]<<8) | (value[2]<<16) | (value[3]<<24) | (value[4]<<32) | (value[5]<<40) | (value[6]<<48) | (value[7]<<56);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int u16_to_u8(u8 *out_value, u16 in_value, u8 endianness)
|
||||
{
|
||||
switch(endianness){
|
||||
case(BE):
|
||||
out_value[0]=(in_value >> 8);
|
||||
out_value[1]=(in_value >> 0);
|
||||
break;
|
||||
case(LE):
|
||||
out_value[0]=(in_value >> 0);
|
||||
out_value[1]=(in_value >> 8);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int u32_to_u8(u8 *out_value, u32 in_value, u8 endianness)
|
||||
{
|
||||
switch(endianness){
|
||||
case(BE):
|
||||
out_value[0]=(in_value >> 24);
|
||||
out_value[1]=(in_value >> 16);
|
||||
out_value[2]=(in_value >> 8);
|
||||
out_value[3]=(in_value >> 0);
|
||||
break;
|
||||
case(LE):
|
||||
out_value[0]=(in_value >> 0);
|
||||
out_value[1]=(in_value >> 8);
|
||||
out_value[2]=(in_value >> 16);
|
||||
out_value[3]=(in_value >> 24);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int u64_to_u8(u8 *out_value, u64 in_value, u8 endianness)
|
||||
{
|
||||
switch(endianness){
|
||||
case(BE):
|
||||
out_value[0]=(in_value >> 56);
|
||||
out_value[1]=(in_value >> 48);
|
||||
out_value[2]=(in_value >> 40);
|
||||
out_value[3]=(in_value >> 32);
|
||||
out_value[4]=(in_value >> 24);
|
||||
out_value[5]=(in_value >> 16);
|
||||
out_value[6]=(in_value >> 8);
|
||||
out_value[7]=(in_value >> 0);
|
||||
break;
|
||||
case(LE):
|
||||
out_value[0]=(in_value >> 0);
|
||||
out_value[1]=(in_value >> 8);
|
||||
out_value[2]=(in_value >> 16);
|
||||
out_value[3]=(in_value >> 24);
|
||||
out_value[4]=(in_value >> 32);
|
||||
out_value[5]=(in_value >> 40);
|
||||
out_value[6]=(in_value >> 48);
|
||||
out_value[7]=(in_value >> 56);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 size;
|
||||
u8 *buffer;
|
||||
} buffer_struct;
|
||||
|
||||
// Memory
|
||||
int CopyData(u8 **dest, const u8 *source, u64 size);
|
||||
void rndset(void *ptr, u64 num);
|
||||
void clrmem(void *ptr, u64 num);
|
||||
|
||||
// MISC
|
||||
u64 roundup(u64 value, u64 alignment);
|
||||
u64 align(u64 value, u64 alignment);
|
||||
u64 min64(u64 a, u64 b);
|
||||
u64 max64(u64 a, u64 b);
|
||||
|
||||
// Strings
|
||||
void memdump(FILE* fout, const char* prefix, const u8* data, u32 size);
|
||||
char* replace_filextention(const char *input, const char *extention);
|
||||
|
||||
// Base64
|
||||
bool IsValidB64Char(char chr);
|
||||
size_t b64_strlen(const char *str);
|
||||
void b64_strcpy(char *dst, const char *src);
|
||||
int b64_decode(u8 *dst, const char *src, size_t dst_size);
|
||||
|
||||
// Pseudo-Random Number Generator
|
||||
void initRand(void);
|
||||
u8 u8GetRand(void);
|
||||
u16 u16GetRand(void);
|
||||
u32 u32GetRand(void);
|
||||
u64 u64GetRand(void);
|
||||
|
||||
//Char IO
|
||||
bool AssertFile(char *filename);
|
||||
u64 GetFileSize64(char *filename);
|
||||
int makedir(const char* dir);
|
||||
int TruncateFile64(char *filename, u64 filelen);
|
||||
|
||||
//IO Misc
|
||||
u8* ImportFile(char *file, u64 size);
|
||||
void WriteBuffer(const void *buffer, u64 size, u64 offset, FILE *output);
|
||||
void ReadFile64(void *outbuff, u64 size, u64 offset, FILE *file);
|
||||
int fseek_64(FILE *fp, u64 file_pos);
|
||||
|
||||
//Data Size conversion
|
||||
u16 u8_to_u16(const u8 *value, u8 endianness);
|
||||
u32 u8_to_u32(const u8 *value, u8 endianness);
|
||||
u64 u8_to_u64(const u8 *value, u8 endianness);
|
||||
int u16_to_u8(u8 *out_value, u16 in_value, u8 endianness);
|
||||
int u32_to_u8(u8 *out_value, u32 in_value, u8 endianness);
|
||||
int u64_to_u8(u8 *out_value, u64 in_value, u8 endianness);
|
||||
@@ -0,0 +1,583 @@
|
||||
#include "lib.h"
|
||||
#include "rsf_settings.h"
|
||||
|
||||
// Private Prototypes
|
||||
void InitYamlContext(ctr_yaml_context *ctx);
|
||||
int ParseSpecFile(rsf_settings *set, char *path, dname_struct *dname);
|
||||
void ProcessYamlString(ctr_yaml_context *ctx);
|
||||
void CheckEvent(ctr_yaml_context *ctx);
|
||||
|
||||
|
||||
void BadYamlFormatting(void);
|
||||
|
||||
// Code
|
||||
int GetRsfSettings(user_settings *set)
|
||||
{
|
||||
int ret = 0;
|
||||
if(set->common.rsfPath) {
|
||||
if(!AssertFile(set->common.rsfPath)) {
|
||||
fprintf(stderr,"[RSF ERROR] Failed to open %s\n",set->common.rsfPath);
|
||||
return FAILED_TO_OPEN_FILE;
|
||||
}
|
||||
ret = ParseSpecFile(&set->common.rsfSet,set->common.rsfPath, &set->dname);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ParseSpecFile(rsf_settings *set, char *path, dname_struct *dname)
|
||||
{
|
||||
ctr_yaml_context *ctx = malloc(sizeof(ctr_yaml_context));
|
||||
InitYamlContext(ctx);
|
||||
|
||||
/* Set Specfile Type */
|
||||
|
||||
/* Create the Parser object. */
|
||||
yaml_parser_initialize(&ctx->parser);
|
||||
|
||||
/* Set a file input. */
|
||||
FILE *input = fopen(path,"rb");
|
||||
yaml_parser_set_input_file(&ctx->parser, input);
|
||||
|
||||
|
||||
ctx->dname = dname;
|
||||
ctx->IsSequence = false;
|
||||
ctx->IsKey = true;
|
||||
ctx->prev_event = 0;
|
||||
ctx->Level = 0;
|
||||
|
||||
|
||||
/* Read the event sequence. */
|
||||
while (!ctx->done) {
|
||||
/* Get the next event. */
|
||||
GetEvent(ctx);
|
||||
if(ctx->error) goto error;
|
||||
|
||||
/* Proccess Event */
|
||||
|
||||
|
||||
if(EventIsScalar(ctx)){
|
||||
EvaluateRSF(set,ctx);
|
||||
if(ctx->error) goto error;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
if((ctx->event.type == YAML_SEQUENCE_START_EVENT|| ctx->event.type == YAML_MAPPING_START_EVENT) && ctx->prev_event == YAML_SCALAR_EVENT) printf(":\n");
|
||||
if(ctx->event.type == YAML_SCALAR_EVENT){
|
||||
if(ctx->IsSequence){
|
||||
printf(" - %s\n",ctx->event.data.scalar.value);
|
||||
}
|
||||
else{
|
||||
if(!ctx->IsKey) printf(": %s\n",ctx->event.data.scalar.value);
|
||||
else printf("%s",ctx->event.data.scalar.value);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* Finish Event */
|
||||
FinishEvent(ctx);
|
||||
if(ctx->error) goto error;
|
||||
}
|
||||
|
||||
/* Destroy the Parser object. */
|
||||
yaml_parser_delete(&ctx->parser);
|
||||
fclose(input);
|
||||
return 0;
|
||||
|
||||
/* On error. */
|
||||
error:
|
||||
fprintf(stderr,"[RSF ERROR] Error Proccessing RSF file\n");
|
||||
|
||||
/* Destroy the Parser object. */
|
||||
yaml_parser_delete(&ctx->parser);
|
||||
fclose(input);
|
||||
return ctx->error;
|
||||
}
|
||||
|
||||
void InitYamlContext(ctr_yaml_context *ctx)
|
||||
{
|
||||
memset(ctx,0,sizeof(ctr_yaml_context));
|
||||
}
|
||||
|
||||
void ProcessYamlString(ctr_yaml_context *ctx)
|
||||
{
|
||||
if(ctx->string)
|
||||
{
|
||||
free(ctx->string);
|
||||
ctx->string = NULL;
|
||||
}
|
||||
|
||||
if(!ctx->event.data.scalar.value)
|
||||
return;
|
||||
|
||||
char *rawStr = (char*)ctx->event.data.scalar.value;
|
||||
int rawStrLen = strlen(rawStr);
|
||||
int procStrLen = 0;
|
||||
|
||||
char *subStart = NULL;
|
||||
char *subEnd = NULL;
|
||||
char *pos = rawStr;
|
||||
char *end = (rawStr+rawStrLen);
|
||||
while(pos < end)
|
||||
{
|
||||
// Find substution syntax in string
|
||||
subStart = strstr(pos,"$(");
|
||||
if(!subStart)
|
||||
{
|
||||
procStrLen += (end - pos);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check For errors
|
||||
if((end - subStart) <= 3) // Valid use of substitution syntax is not possible
|
||||
{
|
||||
ctx->error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
subEnd = strstr((subStart+2),")");
|
||||
|
||||
if(!subEnd) // no closing bracket
|
||||
{
|
||||
ctx->error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Add length of string not accounted for
|
||||
procStrLen += (int)(subStart - pos);
|
||||
|
||||
// Get Length Of substitution key
|
||||
char *subName = (subStart+2);
|
||||
int subNameLen = (int)((subEnd - subStart) - 2);
|
||||
|
||||
// Add length of substitutiion value
|
||||
for(u32 i = 0; i < ctx->dname->u_items; i++){
|
||||
char *testSubName = ctx->dname->items[i].name;
|
||||
int testSubNameLen = strlen(testSubName);
|
||||
char *testSubValue = ctx->dname->items[i].value;
|
||||
int testSubValueLen = strlen(testSubValue);
|
||||
|
||||
if(testSubNameLen != subNameLen)
|
||||
continue;
|
||||
if(strncmp(testSubName,subName,subNameLen) != 0)
|
||||
continue;
|
||||
|
||||
procStrLen += testSubValueLen;
|
||||
break;
|
||||
}
|
||||
|
||||
// Increment pos
|
||||
pos = (subEnd + 1);
|
||||
}
|
||||
|
||||
// Allocate memory for processed string
|
||||
ctx->string = calloc(procStrLen+1,sizeof(char));
|
||||
char *procStr = ctx->string;
|
||||
|
||||
pos = rawStr;
|
||||
end = (rawStr+rawStrLen);
|
||||
while(pos < end)
|
||||
{
|
||||
// Find substution syntax in string
|
||||
subStart = strstr(pos,"$(");
|
||||
if(!subStart)
|
||||
{
|
||||
strncat(procStr,pos,(end - pos));
|
||||
break;
|
||||
}
|
||||
|
||||
// Check For errors
|
||||
if((end - subStart) <= 3) // Valid use of substitution syntax is not possible
|
||||
{
|
||||
ctx->error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
subEnd = strstr((subStart+2),")");
|
||||
|
||||
if(!subEnd) // no closing bracket
|
||||
{
|
||||
ctx->error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Add length of string not accounted for
|
||||
strncat(procStr,pos,(subStart - pos));
|
||||
|
||||
// Get Length Of substitution key
|
||||
char *subName = (subStart+2);
|
||||
int subNameLen = (int)((subEnd - subStart) - 2);
|
||||
|
||||
// Add length of substitutiion value
|
||||
for(u32 i = 0; i < ctx->dname->u_items; i++){
|
||||
char *testSubName = ctx->dname->items[i].name;
|
||||
int testSubNameLen = strlen(testSubName);
|
||||
char *testSubValue = ctx->dname->items[i].value;
|
||||
int testSubValueLen = strlen(testSubValue);
|
||||
|
||||
if(testSubNameLen != subNameLen)
|
||||
continue;
|
||||
if(strncmp(testSubName,subName,subNameLen) != 0)
|
||||
continue;
|
||||
|
||||
strncat(procStr,testSubValue,testSubValueLen);
|
||||
break;
|
||||
}
|
||||
|
||||
// Increment pos
|
||||
pos = (subEnd + 1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
char *GetYamlString(ctr_yaml_context *ctx)
|
||||
{
|
||||
return ctx->string;
|
||||
}
|
||||
|
||||
|
||||
u32 GetYamlStringSize(ctr_yaml_context *ctx)
|
||||
{
|
||||
return strlen(GetYamlString(ctx)); // can't read size from yaml, as string may have been intercepted
|
||||
}
|
||||
|
||||
void GetEvent(ctr_yaml_context *ctx)
|
||||
{
|
||||
if (!yaml_parser_parse(&ctx->parser, &ctx->event)){
|
||||
ctx->error = YAML_API_ERROR;
|
||||
return;
|
||||
}
|
||||
CheckEvent(ctx);
|
||||
}
|
||||
|
||||
void CheckEvent(ctr_yaml_context *ctx)
|
||||
{
|
||||
switch(ctx->event.type){
|
||||
case YAML_SCALAR_EVENT:
|
||||
ProcessYamlString(ctx);
|
||||
break;
|
||||
case YAML_SEQUENCE_START_EVENT:
|
||||
ctx->IsSequence = true;
|
||||
ctx->IsKey = true;
|
||||
ctx->Level++;
|
||||
//printf("[LEVEL] %d\n",ctx->Level);
|
||||
break;
|
||||
case YAML_SEQUENCE_END_EVENT:
|
||||
ctx->IsSequence = false;
|
||||
ctx->IsKey = true;
|
||||
ctx->Level--;
|
||||
//printf("[LEVEL] %d\n",ctx->Level);
|
||||
break;
|
||||
case YAML_MAPPING_START_EVENT:
|
||||
ctx->IsKey = true;
|
||||
ctx->Level++;
|
||||
//printf("[LEVEL] %d\n",ctx->Level);
|
||||
break;
|
||||
case YAML_MAPPING_END_EVENT:
|
||||
ctx->IsKey = true;
|
||||
ctx->Level--;
|
||||
//printf("[LEVEL] %d\n",ctx->Level);
|
||||
break;
|
||||
case YAML_DOCUMENT_END_EVENT:
|
||||
case YAML_STREAM_END_EVENT:
|
||||
ctx->done = true;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void FinishEvent(ctr_yaml_context *ctx)
|
||||
{
|
||||
if(ctx->event.type == YAML_SCALAR_EVENT) {
|
||||
if(!ctx->IsSequence){
|
||||
ctx->IsKey = !ctx->IsKey;
|
||||
//if(!ctx->IsKey)ctx->IsKey = true;
|
||||
//else ctx->IsKey = false;
|
||||
}
|
||||
if(ctx->string){
|
||||
free(ctx->string);
|
||||
ctx->string = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->prev_event = ctx->event.type;
|
||||
yaml_event_delete(&ctx->event);
|
||||
}
|
||||
|
||||
bool EventIsScalar(ctr_yaml_context *ctx)
|
||||
{
|
||||
return (ctx->event.type == YAML_SCALAR_EVENT);
|
||||
}
|
||||
|
||||
bool EventIsMappingStart(ctr_yaml_context *ctx)
|
||||
{
|
||||
return (ctx->event.type == YAML_MAPPING_START_EVENT);
|
||||
}
|
||||
|
||||
bool EventIsMappingEnd(ctr_yaml_context *ctx)
|
||||
{
|
||||
return (ctx->event.type == YAML_MAPPING_END_EVENT);
|
||||
}
|
||||
|
||||
bool EventIsSequenceStart(ctr_yaml_context *ctx)
|
||||
{
|
||||
return (ctx->event.type == YAML_SEQUENCE_START_EVENT);
|
||||
}
|
||||
|
||||
bool EventIsSequenceEnd(ctr_yaml_context *ctx)
|
||||
{
|
||||
return (ctx->event.type == YAML_SEQUENCE_END_EVENT);
|
||||
}
|
||||
|
||||
bool CheckSequenceEvent(ctr_yaml_context *ctx)
|
||||
{
|
||||
GetEvent(ctx);
|
||||
if(!EventIsSequenceStart(ctx)){
|
||||
FinishEvent(ctx);
|
||||
//fprintf(stderr,"[-] Bad formatting in Spec file (Expected Sequence)\n");
|
||||
//ctx->error = YAML_BAD_FORMATTING;
|
||||
return false;
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckMappingEvent(ctr_yaml_context *ctx)
|
||||
{
|
||||
GetEvent(ctx);
|
||||
if(!EventIsMappingStart(ctx)){
|
||||
FinishEvent(ctx);
|
||||
//fprintf(stderr,"[-] Bad formatting in Spec file (Expected Mapping)\n");
|
||||
//ctx->error = YAML_BAD_FORMATTING;
|
||||
return false;
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BadYamlFormatting(void)
|
||||
{
|
||||
fprintf(stderr,"[-] Bad formatting in Spec file\n");
|
||||
}
|
||||
|
||||
|
||||
bool cmpYamlValue(char *string,ctr_yaml_context *ctx)
|
||||
{
|
||||
return (strcmp(GetYamlString(ctx),string) == 0);
|
||||
}
|
||||
|
||||
bool casecmpYamlValue(char *string,ctr_yaml_context *ctx)
|
||||
{
|
||||
return (strcasecmp(GetYamlString(ctx),string) == 0);
|
||||
}
|
||||
|
||||
void SetSimpleYAMLValue(char **dest, char *key, ctr_yaml_context *ctx, u32 size_limit)
|
||||
{
|
||||
if(*dest){
|
||||
fprintf(stderr,"[RSF ERROR] Item '%s' is already set\n",key);
|
||||
ctx->error = YAML_MEM_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
GetEvent(ctx);
|
||||
if(ctx->error || ctx->done) return;
|
||||
if(!EventIsScalar(ctx)){
|
||||
fprintf(stderr,"[RSF ERROR] '%s' requires a value\n",key);
|
||||
ctx->error = YAML_BAD_FORMATTING;
|
||||
return;
|
||||
}
|
||||
if(!GetYamlStringSize(ctx)) return;
|
||||
|
||||
u32 size = GetYamlStringSize(ctx);
|
||||
if(size > size_limit && size_limit) size = size_limit;
|
||||
|
||||
|
||||
char *tmp = *dest;
|
||||
tmp = malloc(size+2);
|
||||
if(!tmp) {
|
||||
ctx->error = YAML_MEM_ERROR;
|
||||
return;
|
||||
}
|
||||
memset(tmp,0,size+2);
|
||||
memcpy(tmp,GetYamlString(ctx),size);
|
||||
|
||||
//printf("Setting %s to %s (size of %d)\n",key,GetYamlString(ctx),size);
|
||||
//printf("Check: %s & %x\n",tmp,tmp);
|
||||
*dest = tmp;
|
||||
|
||||
}
|
||||
|
||||
void SetBoolYAMLValue(bool *dest, char *key, ctr_yaml_context *ctx)
|
||||
{
|
||||
GetEvent(ctx);
|
||||
if(ctx->error || ctx->done) return;
|
||||
if(!EventIsScalar(ctx)){
|
||||
fprintf(stderr,"[RSF ERROR] '%s' requires a value\n",key);
|
||||
ctx->error = YAML_BAD_FORMATTING;
|
||||
return;
|
||||
}
|
||||
if(!GetYamlStringSize(ctx)){
|
||||
fprintf(stderr,"[RSF ERROR] '%s' requires a value\n",key);
|
||||
ctx->error = YAML_BAD_FORMATTING;
|
||||
return;
|
||||
}
|
||||
|
||||
if(casecmpYamlValue("true",ctx))
|
||||
*dest = true;
|
||||
else if(casecmpYamlValue("false",ctx))
|
||||
*dest = false;
|
||||
else{
|
||||
fprintf(stderr,"[RSF ERROR] Invalid '%s'\n",key);
|
||||
ctx->error = YAML_BAD_FORMATTING;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
u32 SetYAMLSequence(char ***dest, char *key, ctr_yaml_context *ctx)
|
||||
{
|
||||
if(*dest){
|
||||
fprintf(stderr,"[RSF ERROR] %s already set\n",key);
|
||||
ctx->error = YAML_MEM_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 ActualCount = 0;
|
||||
u32 SlotCount = 0;
|
||||
char **tmp = *dest;
|
||||
if(!CheckSequenceEvent(ctx)) return 0;
|
||||
SlotCount = 10;
|
||||
tmp = malloc((SlotCount+1)*sizeof(char*));
|
||||
if(!tmp){
|
||||
ctx->error = YAML_MEM_ERROR;
|
||||
return 0;
|
||||
}
|
||||
memset(tmp,0,(SlotCount+1)*sizeof(char*));
|
||||
GetEvent(ctx);
|
||||
if(ctx->error || ctx->done) return 0;
|
||||
if(!EventIsScalar(ctx)){
|
||||
fprintf(stderr,"[RSF ERROR] '%s' requires a value\n",key);
|
||||
ctx->error = YAML_BAD_FORMATTING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(!GetYamlStringSize(ctx)) return 0;
|
||||
u32 InitLevel = ctx->Level;
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return 0;
|
||||
tmp[ActualCount] = malloc(GetYamlStringSize(ctx)+1);
|
||||
memset(tmp[ActualCount],0,GetYamlStringSize(ctx)+1);
|
||||
memcpy(tmp[ActualCount],GetYamlString(ctx),GetYamlStringSize(ctx));
|
||||
ActualCount++;
|
||||
if(ActualCount >= SlotCount){ // if Exceeding Ptr capacity, expand buffer
|
||||
SlotCount = SlotCount*2;
|
||||
/*
|
||||
char **tmp1 = malloc((SlotCount+1)*sizeof(char*)); // allocate new buffer
|
||||
if(!tmp1){
|
||||
ctx->error = YAML_MEM_ERROR;
|
||||
return 0;
|
||||
}
|
||||
memset(tmp1,0,(SlotCount+1)*sizeof(char*));
|
||||
for(u32 i = 0; i < ActualCount; i++) tmp1[i] = tmp[i]; // Transfer ptrs
|
||||
free(tmp); // free original buffer
|
||||
tmp = tmp1; // transfer main ptr
|
||||
*/
|
||||
tmp = realloc(tmp,(SlotCount+1)*sizeof(char*));
|
||||
if(!tmp){
|
||||
ctx->error = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
*dest = tmp; // Give main ptr to location
|
||||
return ActualCount++; // return number of strings
|
||||
}
|
||||
|
||||
u32 SetYAMLSequenceFromMapping(char ***dest, char *key, ctr_yaml_context *ctx, bool StoreKey)
|
||||
{
|
||||
if(*dest){
|
||||
fprintf(stderr,"[RSF ERROR] %s already set\n",key);
|
||||
ctx->error = YAML_MEM_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 ActualCount = 0;
|
||||
u32 SlotCount = 0;
|
||||
char **tmp = *dest;
|
||||
if(!CheckMappingEvent(ctx)) return 0;
|
||||
SlotCount = 10;
|
||||
tmp = malloc((SlotCount+1)*sizeof(char*));
|
||||
if(!tmp){
|
||||
ctx->error = YAML_MEM_ERROR;
|
||||
return 0;
|
||||
}
|
||||
memset(tmp,0,(SlotCount+1)*sizeof(char*));
|
||||
GetEvent(ctx);
|
||||
if(ctx->error || ctx->done) return 0;
|
||||
if(!EventIsScalar(ctx)){
|
||||
fprintf(stderr,"[RSF ERROR] '%s' requires a value\n",key);
|
||||
ctx->error = YAML_BAD_FORMATTING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(!GetYamlStringSize(ctx)) return 0;
|
||||
u32 InitLevel = ctx->Level;
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return 0;
|
||||
if(ctx->IsKey == StoreKey){
|
||||
tmp[ActualCount] = malloc(GetYamlStringSize(ctx)+1);
|
||||
memset(tmp[ActualCount],0,GetYamlStringSize(ctx)+1);
|
||||
memcpy(tmp[ActualCount],GetYamlString(ctx),GetYamlStringSize(ctx));
|
||||
ActualCount++;
|
||||
if(ActualCount >= SlotCount){ // if Exceeding Ptr capacity, expand buffer
|
||||
SlotCount = SlotCount*2;
|
||||
char **tmp1 = malloc((SlotCount+1)*sizeof(char*)); // allocate new buffer
|
||||
if(!tmp1){
|
||||
ctx->error = YAML_MEM_ERROR;
|
||||
return 0;
|
||||
}
|
||||
memset(tmp1,0,(SlotCount+1)*sizeof(char*));
|
||||
for(u32 i = 0; i < ActualCount; i++) tmp1[i] = tmp[i]; // Transfer ptrs
|
||||
free(tmp); // free original buffer
|
||||
tmp = tmp1; // transfer main ptr
|
||||
}
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
*dest = tmp; // Give main ptr to location
|
||||
return ActualCount++; // return number of strings
|
||||
}
|
||||
|
||||
/*
|
||||
void SkipYAMLGroup(ctr_yaml_context *ctx)
|
||||
{
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
if(!EventIsMappingStart(ctx) && !EventIsSequenceStart(ctx) && EventIsScalar(ctx)) return;
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
|
||||
if(ctx->error || ctx->done) return;
|
||||
if(!EventIsScalar(ctx)){
|
||||
fprintf(stderr,"[RSF ERROR] Format error\n");
|
||||
ctx->error = YAML_BAD_FORMATTING;
|
||||
return;
|
||||
}
|
||||
if(!GetYamlStringSize(ctx)) return;
|
||||
u32 InitLevel = ctx->Level;
|
||||
while(ctx->Level == InitLevel){
|
||||
if(ctx->error || ctx->done) return;
|
||||
FinishEvent(ctx);
|
||||
GetEvent(ctx);
|
||||
}
|
||||
FinishEvent(ctx);
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <libyaml/yaml.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
YAML_API_ERROR = -1,
|
||||
YAML_BAD_GROUP_HEADER = -2,
|
||||
YAML_BAD_FORMATTING = -3,
|
||||
YAML_MEM_ERROR = -4,
|
||||
YAML_UNKNOWN_KEY = -5,
|
||||
} ctr_yaml_error;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// For Continued Parsing of file
|
||||
yaml_parser_t parser;
|
||||
yaml_event_t event;
|
||||
bool done;
|
||||
int error;
|
||||
|
||||
// Important Details
|
||||
dname_struct *dname;
|
||||
bool IsSequence;
|
||||
bool IsKey;
|
||||
yaml_event_type_t prev_event;
|
||||
u32 Level;
|
||||
|
||||
// Processed String
|
||||
char *string;
|
||||
} ctr_yaml_context;
|
||||
|
||||
// Public Prototypes
|
||||
int GetRsfSettings(user_settings *set);
|
||||
|
||||
// For scalar events
|
||||
char *GetYamlString(ctr_yaml_context *ctx);
|
||||
u32 GetYamlStringSize(ctr_yaml_context *ctx);
|
||||
bool cmpYamlValue(char *string,ctr_yaml_context *ctx); // Compares a string to the current scalar event
|
||||
bool casecmpYamlValue(char *string,ctr_yaml_context *ctx); // same as above but ignores case
|
||||
|
||||
// Event Handlers
|
||||
void GetEvent(ctr_yaml_context *ctx);
|
||||
void FinishEvent(ctr_yaml_context *ctx);
|
||||
|
||||
|
||||
// Event Type Checks
|
||||
bool EventIsScalar(ctr_yaml_context *ctx);
|
||||
bool EventIsMappingStart(ctr_yaml_context *ctx);
|
||||
bool EventIsMappingEnd(ctr_yaml_context *ctx);
|
||||
bool EventIsSequenceStart(ctr_yaml_context *ctx);
|
||||
bool EventIsSequenceEnd(ctr_yaml_context *ctx);
|
||||
bool CheckMappingEvent(ctr_yaml_context *ctx); // With extra implement, use if lazy
|
||||
bool CheckSequenceEvent(ctr_yaml_context *ctx); // With extra implement, use if lazy
|
||||
|
||||
|
||||
// Functions which store values
|
||||
void SetSimpleYAMLValue(char **dest, char *key, ctr_yaml_context *ctx, u32 size_limit);
|
||||
void SetBoolYAMLValue(bool *dest, char *key, ctr_yaml_context *ctx);
|
||||
u32 SetYAMLSequence(char ***dest, char *key, ctr_yaml_context *ctx);
|
||||
u32 SetYAMLSequenceFromMapping(char ***dest, char *key, ctr_yaml_context *ctx, bool StoreKey);
|
||||
//void SkipYAMLGroup(ctr_yaml_context *ctx);
|
||||
Reference in New Issue
Block a user