2018-04-21 09:37:30 +00:00
|
|
|
#pragma once
|
2018-04-07 08:04:45 +00:00
|
|
|
#include <string>
|
|
|
|
#include <fnd/types.h>
|
|
|
|
#include <fnd/List.h>
|
|
|
|
#include <crypto/aes.h>
|
|
|
|
#include <crypto/sha.h>
|
2018-04-21 09:37:30 +00:00
|
|
|
#include <crypto/rsa.h>
|
2018-04-07 08:04:45 +00:00
|
|
|
#include <fnd/ISerialiseableBinary.h>
|
2018-06-03 07:41:56 +00:00
|
|
|
#include <nx/macro.h>
|
2018-04-07 08:04:45 +00:00
|
|
|
|
|
|
|
namespace nx
|
|
|
|
{
|
|
|
|
namespace xci
|
|
|
|
{
|
2018-06-03 07:41:56 +00:00
|
|
|
static const uint32_t kXciSig = _MAKE_STRUCT_SIGNATURE("HEAD");
|
2018-04-07 08:04:45 +00:00
|
|
|
static const uint32_t kHeaderEncOffset = 0x90;
|
|
|
|
static const uint32_t kHeaderEncSize = 0x70;
|
|
|
|
static const uint32_t kPageSize = 0x200;
|
2018-04-21 09:37:30 +00:00
|
|
|
static const uint32_t kUppHashLen = 8;
|
2018-04-07 08:04:45 +00:00
|
|
|
static const uint32_t kCardKeyAreaPageCount = 8;
|
|
|
|
static const uint32_t kCardHeaderPageCount = 1;
|
|
|
|
static const uint32_t kReservedAreaPageCount = 55;
|
|
|
|
static const uint32_t kCertAreaStartPageAddress = kCardHeaderPageCount + kReservedAreaPageCount + kCardKeyAreaPageCount;
|
|
|
|
static const uint32_t kCertAreaPageCount = 64;
|
|
|
|
static const uint32_t kNormalAreaStartPageAddress = kReservedAreaPageCount + kCertAreaPageCount + kCardHeaderPageCount + kCardKeyAreaPageCount;
|
|
|
|
|
2018-06-03 07:10:47 +00:00
|
|
|
const std::string kUpdatePartitionStr = "update";
|
|
|
|
const std::string kNormalPartitionStr = "normal";
|
|
|
|
const std::string kSecurePartitionStr = "secure";
|
|
|
|
const std::string kLogoPartitionStr = "logo";
|
|
|
|
|
2018-04-07 08:04:45 +00:00
|
|
|
|
2018-04-21 09:37:30 +00:00
|
|
|
enum KekIndex
|
|
|
|
{
|
|
|
|
KEK_XCIE,
|
|
|
|
KEK_XCIR
|
|
|
|
};
|
|
|
|
|
2018-04-07 08:04:45 +00:00
|
|
|
enum RomSize
|
|
|
|
{
|
|
|
|
ROM_SIZE_1GB = 0xFA,
|
|
|
|
ROM_SIZE_2GB = 0xF8,
|
|
|
|
ROM_SIZE_4GB = 0xF0,
|
|
|
|
ROM_SIZE_8GB = 0xE0,
|
|
|
|
ROM_SIZE_16GB = 0xE1,
|
|
|
|
ROM_SIZE_32GB = 0xE2
|
|
|
|
};
|
|
|
|
|
|
|
|
enum HeaderFlags
|
|
|
|
{
|
|
|
|
FLAG_AUTOBOOT,
|
|
|
|
FLAG_HISTORY_ERASE,
|
|
|
|
FLAG_REPAIR_TOOL
|
|
|
|
};
|
|
|
|
|
|
|
|
enum FwVersionIndex
|
|
|
|
{
|
|
|
|
FWVER_MINOR,
|
|
|
|
FWVER_MAJOR
|
|
|
|
};
|
|
|
|
|
|
|
|
enum CardClockRate
|
|
|
|
{
|
|
|
|
CLOCK_RATE_25 = 10551312,
|
|
|
|
CLOCK_RATE_50 = 10551313,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma pack(push,1)
|
|
|
|
struct sXciHeader
|
|
|
|
{
|
2018-06-03 07:41:56 +00:00
|
|
|
le_uint32_t signature;
|
2018-04-07 08:04:45 +00:00
|
|
|
le_uint32_t rom_area_start_page;
|
|
|
|
le_uint32_t backup_area_start_page;
|
|
|
|
byte_t key_flag;
|
|
|
|
byte_t rom_size;
|
|
|
|
byte_t card_header_version;
|
|
|
|
byte_t flags;
|
|
|
|
le_uint64_t package_id;
|
|
|
|
le_uint32_t valid_data_end_page;
|
2018-04-21 09:37:30 +00:00
|
|
|
byte_t reserved_00[4];
|
|
|
|
crypto::aes::sAesIvCtr aescbc_iv;
|
2018-04-07 08:04:45 +00:00
|
|
|
le_uint64_t partition_fs_header_address;
|
|
|
|
le_uint64_t partition_fs_header_size;
|
2018-04-21 09:37:30 +00:00
|
|
|
crypto::sha::sSha256Hash partition_fs_header_hash;
|
|
|
|
crypto::sha::sSha256Hash initial_data_hash;
|
2018-04-07 08:04:45 +00:00
|
|
|
le_uint32_t sel_sec;
|
|
|
|
le_uint32_t sel_t1_key;
|
|
|
|
le_uint32_t sel_key;
|
|
|
|
le_uint32_t lim_area;
|
|
|
|
// START ENCRYPTION
|
|
|
|
le_uint32_t fw_version[2];
|
|
|
|
le_uint32_t acc_ctrl_1;
|
|
|
|
le_uint32_t wait_1_time_read;
|
|
|
|
le_uint32_t wait_2_time_read;
|
|
|
|
le_uint32_t wait_1_time_write;
|
|
|
|
le_uint32_t wait_2_time_write;
|
|
|
|
le_uint32_t fw_mode;
|
|
|
|
le_uint32_t upp_version;
|
2018-04-21 09:37:30 +00:00
|
|
|
byte_t reserved_01[0x4];
|
|
|
|
byte_t upp_hash[xci::kUppHashLen];
|
2018-04-07 08:04:45 +00:00
|
|
|
le_uint64_t upp_id;
|
2018-04-21 09:37:30 +00:00
|
|
|
byte_t reserved_02[0x38];
|
2018-04-07 08:04:45 +00:00
|
|
|
// END ENCRYPTION
|
|
|
|
};
|
|
|
|
|
2018-04-21 09:37:30 +00:00
|
|
|
struct sXciHeaderPage
|
|
|
|
{
|
|
|
|
byte_t signature[crypto::rsa::kRsa2048Size];
|
|
|
|
sXciHeader header;
|
|
|
|
}; // sizeof() = 512 (1 page)
|
|
|
|
|
2018-04-07 08:04:45 +00:00
|
|
|
struct sInitialData
|
|
|
|
{
|
|
|
|
byte_t key_source[16]; // { package_id[8], zeros[8]}
|
|
|
|
byte_t title_key_enc[16];
|
|
|
|
byte_t ccm_mac[16];
|
|
|
|
byte_t ccm_nonce[12];
|
|
|
|
}; // sizeof() = 512 (1 page)
|
|
|
|
|
|
|
|
struct sKeyDataArea
|
|
|
|
{
|
|
|
|
sInitialData initial_data; // AES128-CCM encrypted {titlekey[16]}
|
2018-05-15 13:26:40 +00:00
|
|
|
byte_t reserved_00[xci::kPageSize - sizeof(sInitialData)];
|
|
|
|
byte_t encrypted_00[xci::kPageSize * 6]; // AES128-CTR encrypted {titlekey[16]}
|
|
|
|
byte_t encrypted_00_aesctr_data[crypto::rsa::kRsa2048Size]; // RSA2048-OAEP-SHA256 encrypted AES-CTR data used for encrypted_00 {key[16],iv[16]}
|
|
|
|
byte_t reserved_01[xci::kPageSize - crypto::rsa::kRsa2048Size];
|
2018-04-07 08:04:45 +00:00
|
|
|
}; // sizeof() = 512*8 (8 pages)
|
2018-05-15 13:26:40 +00:00
|
|
|
|
2018-04-07 08:04:45 +00:00
|
|
|
#pragma pack(pop)
|
|
|
|
}
|