mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-22 18:26:39 +00:00
More NCA changes.
This commit is contained in:
parent
9e337a5d0a
commit
8ce253d13d
4 changed files with 74 additions and 61 deletions
|
@ -37,7 +37,11 @@ extern "C" {
|
|||
#define NCA_NCA2_MAGIC 0x4E434132 /* "NCA2". */
|
||||
#define NCA_NCA3_MAGIC 0x4E434133 /* "NCA3". */
|
||||
|
||||
#define NCA_USED_KEY_AREA_SIZE sizeof(NcaDecryptedKeyArea) /* Four keys, 0x40 bytes. */
|
||||
#define NCA_KEY_AREA_KEY_COUNT 0x10
|
||||
#define NCA_KEY_AREA_SIZE (NCA_KEY_AREA_KEY_COUNT * AES_128_KEY_SIZE)
|
||||
|
||||
#define NCA_KEY_AREA_USED_KEY_COUNT 3
|
||||
#define NCA_KEY_AREA_USED_SIZE (NCA_KEY_AREA_USED_KEY_COUNT * AES_128_KEY_SIZE)
|
||||
|
||||
#define NCA_HIERARCHICAL_SHA256_MAX_REGION_COUNT 5
|
||||
|
||||
|
@ -121,18 +125,22 @@ typedef struct {
|
|||
NXDT_ASSERT(NcaFsHeaderHash, 0x20);
|
||||
|
||||
/// Encrypted NCA key area used to hold NCA FS section encryption keys. Zeroed out if the NCA uses titlekey crypto.
|
||||
/// Only the first 4 key entries are encrypted.
|
||||
/// If a particular key entry is unused, it is zeroed out before this area is encrypted.
|
||||
typedef struct {
|
||||
union {
|
||||
u8 keys[NCA_KEY_AREA_KEY_COUNT][AES_128_KEY_SIZE];
|
||||
struct {
|
||||
u8 aes_xts_1[AES_128_KEY_SIZE]; ///< AES-128-XTS key 0 used for NCA FS sections with NcaEncryptionType_AesXts crypto.
|
||||
u8 aes_xts_2[AES_128_KEY_SIZE]; ///< AES-128-XTS key 1 used for NCA FS sections with NcaEncryptionType_AesXts crypto.
|
||||
u8 aes_ctr[AES_128_KEY_SIZE]; ///< AES-128-CTR key used for NCA FS sections with NcaEncryptionType_AesCtr crypto.
|
||||
u8 aes_ctr_ex[AES_128_KEY_SIZE]; ///< AES-128-CTR key used for NCA FS sections with NcaEncryptionType_AesCtrEx crypto.
|
||||
u8 aes_ctr[AES_128_KEY_SIZE]; ///< AES-128-CTR key used for NCA FS sections with NcaEncryptionType_AesCtr* and NcaEncryptionType_AesCtrEx* crypto.
|
||||
u8 aes_ctr_ex[AES_128_KEY_SIZE]; ///< Unused AES-128-CTR key.
|
||||
u8 aes_ctr_hw[AES_128_KEY_SIZE]; ///< Unused AES-128-CTR key.
|
||||
u8 reserved[0xB0];
|
||||
};
|
||||
};
|
||||
} NcaEncryptedKeyArea;
|
||||
|
||||
NXDT_ASSERT(NcaEncryptedKeyArea, 0x100);
|
||||
NXDT_ASSERT(NcaEncryptedKeyArea, NCA_KEY_AREA_SIZE);
|
||||
|
||||
/// First 0x400 bytes from every NCA.
|
||||
typedef struct {
|
||||
|
@ -183,6 +191,12 @@ typedef enum {
|
|||
NcaEncryptionType_AesCtrExSkipLayerHash = 6
|
||||
} NcaEncryptionType;
|
||||
|
||||
typedef enum {
|
||||
NcaMetaDataHashType_None = 0,
|
||||
NcaMetaDataHashType_HierarchicalIntegrity = 1,
|
||||
NcaMetaDataHashType_HierarchicalIntegritySha3 = 2
|
||||
} NcaMetaDataHashType;
|
||||
|
||||
typedef struct {
|
||||
u64 offset;
|
||||
u64 size;
|
||||
|
@ -270,7 +284,7 @@ typedef struct {
|
|||
|
||||
NXDT_ASSERT(NcaBucketInfo, 0x20);
|
||||
|
||||
/// Only used for NcaEncryptionType_AesCtrEx (PatchRomFs).
|
||||
/// Only used for NcaEncryptionType_AesCtrEx and NcaEncryptionType_AesCtrExSkipLayerHash (PatchRomFs).
|
||||
typedef struct {
|
||||
NcaBucketInfo indirect_bucket;
|
||||
NcaBucketInfo aes_ctr_ex_bucket;
|
||||
|
@ -323,13 +337,14 @@ typedef struct {
|
|||
u8 fs_type; ///< NcaFsType.
|
||||
u8 hash_type; ///< NcaHashType.
|
||||
u8 encryption_type; ///< NcaEncryptionType.
|
||||
u8 reserved_1[0x3];
|
||||
u8 metadata_hash_type; ///< NcaMetaDataHashType.
|
||||
u8 reserved_1[0x2];
|
||||
NcaHashData hash_data;
|
||||
NcaPatchInfo patch_info;
|
||||
NcaAesCtrUpperIv aes_ctr_upper_iv;
|
||||
NcaSparseInfo sparse_info;
|
||||
NcaCompressionInfo compression_info;
|
||||
NcaMetaDataHashDataInfo hash_data_info;
|
||||
NcaMetaDataHashDataInfo metadata_hash_info;
|
||||
u8 reserved_2[0x30];
|
||||
} NcaFsHeader;
|
||||
|
||||
|
@ -378,13 +393,17 @@ typedef enum {
|
|||
} NcaVersion;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
u8 keys[NCA_KEY_AREA_USED_KEY_COUNT][AES_128_KEY_SIZE];
|
||||
struct {
|
||||
u8 aes_xts_1[AES_128_KEY_SIZE]; ///< AES-128-XTS key 0 used for NCA FS sections with NcaEncryptionType_AesXts crypto.
|
||||
u8 aes_xts_2[AES_128_KEY_SIZE]; ///< AES-128-XTS key 1 used for NCA FS sections with NcaEncryptionType_AesXts crypto.
|
||||
u8 aes_ctr[AES_128_KEY_SIZE]; ///< AES-128-CTR key used for NCA FS sections with NcaEncryptionType_AesCtr crypto.
|
||||
u8 aes_ctr_ex[AES_128_KEY_SIZE]; ///< AES-128-CTR key used for NCA FS sections with NcaEncryptionType_AesCtrEx crypto.
|
||||
u8 aes_ctr[AES_128_KEY_SIZE]; ///< AES-128-CTR key used for NCA FS sections with NcaEncryptionType_AesCtr and NcaEncryptionType_AesCtrSkipLayerHash crypto.
|
||||
};
|
||||
};
|
||||
} NcaDecryptedKeyArea;
|
||||
|
||||
NXDT_ASSERT(NcaDecryptedKeyArea, 0x40);
|
||||
NXDT_ASSERT(NcaDecryptedKeyArea, NCA_KEY_AREA_USED_SIZE);
|
||||
|
||||
typedef struct {
|
||||
u8 storage_id; ///< NcmStorageId.
|
||||
|
|
|
@ -103,8 +103,8 @@ typedef enum {
|
|||
typedef struct {
|
||||
u32 production : 1;
|
||||
u32 unqualified_approval : 1;
|
||||
u32 memory_region : 5; ///< NpdmMemoryRegion.
|
||||
u32 reserved : 25;
|
||||
u32 memory_region : 4; ///< NpdmMemoryRegion.
|
||||
u32 reserved : 26;
|
||||
} NpdmAcidFlags;
|
||||
|
||||
NXDT_ASSERT(NpdmAcidFlags, 0x4);
|
||||
|
|
|
@ -40,8 +40,9 @@ bool bktrInitializeContext(BktrContext *out, NcaFsSectionContext *base_nca_fs_ct
|
|||
|
||||
if (!out || !base_nca_fs_ctx || !(base_nca_ctx = (NcaContext*)base_nca_fs_ctx->nca_ctx) || \
|
||||
!update_nca_fs_ctx || !update_nca_fs_ctx->enabled || !(update_nca_ctx = (NcaContext*)update_nca_fs_ctx->nca_ctx) || \
|
||||
update_nca_fs_ctx->section_type != NcaFsSectionType_PatchRomFs || update_nca_fs_ctx->encryption_type != NcaEncryptionType_AesCtrEx || \
|
||||
base_nca_ctx->header.program_id != update_nca_ctx->header.program_id || base_nca_ctx->header.content_type != update_nca_ctx->header.content_type || \
|
||||
update_nca_fs_ctx->section_type != NcaFsSectionType_PatchRomFs || (update_nca_fs_ctx->encryption_type != NcaEncryptionType_AesCtrEx && \
|
||||
update_nca_fs_ctx->encryption_type != NcaEncryptionType_AesCtrExSkipLayerHash) || base_nca_ctx->header.program_id != update_nca_ctx->header.program_id || \
|
||||
base_nca_ctx->header.content_type != update_nca_ctx->header.content_type || \
|
||||
__builtin_bswap32(update_nca_fs_ctx->header.patch_info.indirect_bucket.header.magic) != NCA_BKTR_MAGIC || \
|
||||
update_nca_fs_ctx->header.patch_info.indirect_bucket.header.version != NCA_BKTR_VERSION || \
|
||||
__builtin_bswap32(update_nca_fs_ctx->header.patch_info.aes_ctr_ex_bucket.header.magic) != NCA_BKTR_MAGIC || \
|
||||
|
@ -58,7 +59,8 @@ bool bktrInitializeContext(BktrContext *out, NcaFsSectionContext *base_nca_fs_ct
|
|||
bktrFreeContext(out);
|
||||
|
||||
/* Update missing base NCA RomFS status. */
|
||||
out->missing_base_romfs = (!base_nca_fs_ctx->enabled || base_nca_fs_ctx->section_type != NcaFsSectionType_RomFs || base_nca_fs_ctx->encryption_type == NcaEncryptionType_AesCtrEx);
|
||||
out->missing_base_romfs = (!base_nca_fs_ctx->enabled || base_nca_fs_ctx->section_type != NcaFsSectionType_RomFs || \
|
||||
(base_nca_fs_ctx->encryption_type != NcaEncryptionType_AesCtr && base_nca_fs_ctx->encryption_type != NcaEncryptionType_AesCtrSkipLayerHash));
|
||||
|
||||
/* Initialize base NCA RomFS context. */
|
||||
if (!out->missing_base_romfs && !romfsInitializeContext(&(out->base_romfs_ctx), base_nca_fs_ctx))
|
||||
|
|
|
@ -278,7 +278,7 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
|
|||
|
||||
/* Initialize crypto data. */
|
||||
if ((!out->rights_id_available || (out->rights_id_available && out->titlekey_retrieved)) && fs_ctx->encryption_type > NcaEncryptionType_None && \
|
||||
fs_ctx->encryption_type <= NcaEncryptionType_AesCtrEx)
|
||||
fs_ctx->encryption_type <= NcaEncryptionType_AesCtrExSkipLayerHash)
|
||||
{
|
||||
/* Initialize the partial AES counter for this section. */
|
||||
aes128CtrInitializePartialCtr(fs_ctx->ctr, fs_ctx->header.aes_ctr_upper_iv.value, fs_ctx->section_offset);
|
||||
|
@ -306,18 +306,12 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
|
|||
aes128XtsContextCreate(&(fs_ctx->xts_decrypt_ctx), out->decrypted_key_area.aes_xts_1, out->decrypted_key_area.aes_xts_2, false);
|
||||
aes128XtsContextCreate(&(fs_ctx->xts_encrypt_ctx), out->decrypted_key_area.aes_xts_1, out->decrypted_key_area.aes_xts_2, true);
|
||||
} else
|
||||
if (fs_ctx->encryption_type == NcaEncryptionType_AesCtr || fs_ctx->encryption_type == NcaEncryptionType_AesCtrEx)
|
||||
if (fs_ctx->encryption_type >= NcaEncryptionType_AesCtr && fs_ctx->encryption_type <= NcaEncryptionType_AesCtrExSkipLayerHash)
|
||||
{
|
||||
/* Patch RomFS sections also use the AES-128-CTR key from the decrypted NCA key area, for some reason. */
|
||||
aes128CtrContextCreate(&(fs_ctx->ctr_ctx), out->decrypted_key_area.aes_ctr, fs_ctx->ctr);
|
||||
if (fs_ctx->has_sparse_layer) aes128CtrContextCreate(&(fs_ctx->sparse_ctr_ctx), out->decrypted_key_area.aes_ctr, fs_ctx->sparse_ctr);
|
||||
} /***else
|
||||
if (fs_ctx->encryption_type == NcaEncryptionType_AesCtr)
|
||||
{
|
||||
aes128CtrContextCreate(&(fs_ctx->ctr_ctx), out->decrypted_key_area.aes_ctr, fs_ctx->ctr);
|
||||
} else {
|
||||
aes128CtrContextCreate(&(fs_ctx->ctr_ctx), out->decrypted_key_area.aes_ctr_ex, fs_ctx->ctr);
|
||||
}***/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,15 +449,6 @@ bool ncaRemoveTitleKeyCrypto(NcaContext *ctx)
|
|||
/* Patch RomFS sections also use the AES-128-CTR key from the decrypted NCA key area, for some reason. */
|
||||
memcpy(ctx->decrypted_key_area.aes_ctr, ctx->titlekey, AES_128_KEY_SIZE);
|
||||
|
||||
/***for(u8 i = 0; i < NCA_FS_HEADER_COUNT; i++)
|
||||
{
|
||||
NcaFsSectionContext *fs_ctx = &(ctx->fs_ctx[i]);
|
||||
if (!fs_ctx->enabled || (fs_ctx->encryption_type != NcaEncryptionType_AesCtr && fs_ctx->encryption_type != NcaEncryptionType_AesCtrEx)) continue;
|
||||
|
||||
u8 *key_ptr = (fs_ctx->encryption_type == NcaEncryptionType_AesCtr ? ctx->decrypted_key_area.aes_ctr : ctx->decrypted_key_area.aes_ctr_ex);
|
||||
memcpy(key_ptr, ctx->titlekey, AES_128_KEY_SIZE);
|
||||
}***/
|
||||
|
||||
/* Encrypt NCA key area. */
|
||||
if (!ncaEncryptKeyArea(ctx))
|
||||
{
|
||||
|
@ -719,23 +704,25 @@ static bool ncaDecryptKeyArea(NcaContext *ctx)
|
|||
}
|
||||
|
||||
const u8 null_key[AES_128_KEY_SIZE] = {0};
|
||||
u8 key_count = (ctx->format_version == NcaVersion_Nca0 ? 2 : 4);
|
||||
|
||||
u8 key_count = NCA_KEY_AREA_USED_KEY_COUNT;
|
||||
if (ctx->format_version == NcaVersion_Nca0) key_count--;
|
||||
|
||||
/* Check if we're dealing with a NCA0 with a plaintext key area. */
|
||||
if (ncaIsVersion0KeyAreaEncrypted(ctx))
|
||||
{
|
||||
memcpy(&(ctx->decrypted_key_area), &(ctx->header.encrypted_key_area), NCA_USED_KEY_AREA_SIZE);
|
||||
memcpy(&(ctx->decrypted_key_area), &(ctx->header.encrypted_key_area), sizeof(NcaDecryptedKeyArea));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Clear decrypted key area. */
|
||||
memset(&(ctx->decrypted_key_area), 0, NCA_USED_KEY_AREA_SIZE);
|
||||
memset(&(ctx->decrypted_key_area), 0, sizeof(NcaDecryptedKeyArea));
|
||||
|
||||
/* Process key area. */
|
||||
for(u8 i = 0; i < key_count; i++)
|
||||
{
|
||||
const u8 *src_key = ((u8*)&(ctx->header.encrypted_key_area) + (i * AES_128_KEY_SIZE));
|
||||
u8 *dst_key = ((u8*)&(ctx->decrypted_key_area) + (i * AES_128_KEY_SIZE));
|
||||
const u8 *src_key = ctx->header.encrypted_key_area.keys[i];
|
||||
u8 *dst_key = ctx->decrypted_key_area.keys[i];
|
||||
|
||||
/* Don't proceed if we're dealing with a null key. */
|
||||
if (!memcmp(src_key, null_key, AES_128_KEY_SIZE)) continue;
|
||||
|
@ -759,14 +746,16 @@ static bool ncaEncryptKeyArea(NcaContext *ctx)
|
|||
return false;
|
||||
}
|
||||
|
||||
u8 key_count = (ctx->format_version == NcaVersion_Nca0 ? 2 : 4);
|
||||
u8 key_count = NCA_KEY_AREA_USED_KEY_COUNT;
|
||||
if (ctx->format_version == NcaVersion_Nca0) key_count--;
|
||||
|
||||
const u8 *kaek = NULL, null_key[AES_128_KEY_SIZE] = {0};
|
||||
Aes128Context key_area_ctx = {0};
|
||||
|
||||
/* Check if we're dealing with a NCA0 with a plaintext key area. */
|
||||
if (ncaIsVersion0KeyAreaEncrypted(ctx))
|
||||
{
|
||||
memcpy(&(ctx->header.encrypted_key_area), &(ctx->decrypted_key_area), NCA_USED_KEY_AREA_SIZE);
|
||||
memcpy(&(ctx->header.encrypted_key_area), &(ctx->decrypted_key_area), sizeof(NcaDecryptedKeyArea));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -787,8 +776,8 @@ static bool ncaEncryptKeyArea(NcaContext *ctx)
|
|||
/* Process key area. */
|
||||
for(u8 i = 0; i < key_count; i++)
|
||||
{
|
||||
const u8 *src_key = ((u8*)&(ctx->decrypted_key_area) + (i * AES_128_KEY_SIZE));
|
||||
u8 *dst_key = ((u8*)&(ctx->header.encrypted_key_area) + (i * AES_128_KEY_SIZE));
|
||||
const u8 *src_key = ctx->decrypted_key_area.keys[i];
|
||||
u8 *dst_key = ctx->header.encrypted_key_area.keys[i];
|
||||
|
||||
/* Don't proceed if we're dealing with a null key. */
|
||||
if (!memcmp(src_key, null_key, AES_128_KEY_SIZE)) continue;
|
||||
|
@ -822,7 +811,7 @@ NX_INLINE bool ncaIsVersion0KeyAreaEncrypted(NcaContext *ctx)
|
|||
if (!ctx || ctx->format_version != NcaVersion_Nca0) return false;
|
||||
|
||||
u8 nca0_key_area_hash[SHA256_HASH_SIZE] = {0};
|
||||
sha256CalculateHash(nca0_key_area_hash, &(ctx->header.encrypted_key_area), NCA_USED_KEY_AREA_SIZE);
|
||||
sha256CalculateHash(nca0_key_area_hash, &(ctx->header.encrypted_key_area), 4 * AES_128_KEY_SIZE);
|
||||
return (memcmp(nca0_key_area_hash, g_nca0KeyAreaHash, SHA256_HASH_SIZE) != 0);
|
||||
}
|
||||
|
||||
|
@ -847,8 +836,8 @@ NX_INLINE bool ncaCheckRightsIdAvailability(NcaContext *ctx)
|
|||
static bool _ncaReadFsSection(NcaFsSectionContext *ctx, void *out, u64 read_size, u64 offset)
|
||||
{
|
||||
if (!g_ncaCryptoBuffer || !ctx || !ctx->enabled || !ctx->nca_ctx || ctx->section_num >= NCA_FS_HEADER_COUNT || ctx->section_offset < sizeof(NcaHeader) || \
|
||||
ctx->section_type >= NcaFsSectionType_Invalid || ctx->encryption_type == NcaEncryptionType_Auto || ctx->encryption_type > NcaEncryptionType_AesCtrEx || !out || !read_size || \
|
||||
(offset + read_size) > ctx->section_size)
|
||||
ctx->section_type >= NcaFsSectionType_Invalid || ctx->encryption_type == NcaEncryptionType_Auto || ctx->encryption_type > NcaEncryptionType_AesCtrExSkipLayerHash || \
|
||||
!out || !read_size || (offset + read_size) > ctx->section_size)
|
||||
{
|
||||
LOG_MSG("Invalid NCA FS section header parameters!");
|
||||
return false;
|
||||
|
@ -875,7 +864,7 @@ static bool _ncaReadFsSection(NcaFsSectionContext *ctx, void *out, u64 read_size
|
|||
/* Optimization for reads from plaintext FS sections or reads that are aligned to the AES-CTR / AES-XTS sector size. */
|
||||
if (ctx->encryption_type == NcaEncryptionType_None || \
|
||||
(ctx->encryption_type == NcaEncryptionType_AesXts && !(content_offset % NCA_AES_XTS_SECTOR_SIZE) && !(read_size % NCA_AES_XTS_SECTOR_SIZE)) || \
|
||||
((ctx->encryption_type == NcaEncryptionType_AesCtr || ctx->encryption_type == NcaEncryptionType_AesCtrEx) && !(content_offset % AES_BLOCK_SIZE) && !(read_size % AES_BLOCK_SIZE)))
|
||||
(ctx->encryption_type >= NcaEncryptionType_AesCtr && ctx->encryption_type <= NcaEncryptionType_AesCtrExSkipLayerHash && !(content_offset % AES_BLOCK_SIZE) && !(read_size % AES_BLOCK_SIZE)))
|
||||
{
|
||||
/* Read data. */
|
||||
if (!ncaReadContentFile(nca_ctx, out, read_size, content_offset))
|
||||
|
@ -904,7 +893,7 @@ static bool _ncaReadFsSection(NcaFsSectionContext *ctx, void *out, u64 read_size
|
|||
goto end;
|
||||
}
|
||||
} else
|
||||
if (ctx->encryption_type == NcaEncryptionType_AesCtr || ctx->encryption_type == NcaEncryptionType_AesCtrEx)
|
||||
if (ctx->encryption_type >= NcaEncryptionType_AesCtr && ctx->encryption_type <= NcaEncryptionType_AesCtrExSkipLayerHash)
|
||||
{
|
||||
aes128CtrUpdatePartialCtr(ctx->ctr, content_offset);
|
||||
aes128CtrContextResetCtr(&(ctx->ctr_ctx), ctx->ctr);
|
||||
|
@ -945,7 +934,7 @@ static bool _ncaReadFsSection(NcaFsSectionContext *ctx, void *out, u64 read_size
|
|||
goto end;
|
||||
}
|
||||
} else
|
||||
if (ctx->encryption_type == NcaEncryptionType_AesCtr || ctx->encryption_type == NcaEncryptionType_AesCtrEx)
|
||||
if (ctx->encryption_type >= NcaEncryptionType_AesCtr && ctx->encryption_type <= NcaEncryptionType_AesCtrExSkipLayerHash)
|
||||
{
|
||||
aes128CtrUpdatePartialCtr(ctx->ctr, block_start_offset);
|
||||
aes128CtrContextResetCtr(&(ctx->ctr_ctx), ctx->ctr);
|
||||
|
@ -964,7 +953,8 @@ end:
|
|||
static bool _ncaReadAesCtrExStorageFromBktrSection(NcaFsSectionContext *ctx, void *out, u64 read_size, u64 offset, u32 ctr_val)
|
||||
{
|
||||
if (!g_ncaCryptoBuffer || !ctx || !ctx->enabled || !ctx->nca_ctx || ctx->section_num >= NCA_FS_HEADER_COUNT || ctx->section_offset < sizeof(NcaHeader) || \
|
||||
ctx->section_type != NcaFsSectionType_PatchRomFs || ctx->encryption_type != NcaEncryptionType_AesCtrEx || !out || !read_size || (offset + read_size) > ctx->section_size)
|
||||
ctx->section_type != NcaFsSectionType_PatchRomFs || (ctx->encryption_type != NcaEncryptionType_AesCtrEx && ctx->encryption_type != NcaEncryptionType_AesCtrExSkipLayerHash) || \
|
||||
!out || !read_size || (offset + read_size) > ctx->section_size)
|
||||
{
|
||||
LOG_MSG("Invalid NCA FS section header parameters!");
|
||||
return false;
|
||||
|
@ -1277,9 +1267,11 @@ static void *_ncaGenerateEncryptedFsSectionBlock(NcaFsSectionContext *ctx, const
|
|||
u8 *out = NULL;
|
||||
bool success = false;
|
||||
|
||||
// TODO: add support for Sha3 layers and SkipLayer crypto types.
|
||||
if (!g_ncaCryptoBuffer || !ctx || !ctx->enabled || ctx->has_sparse_layer || !ctx->nca_ctx || ctx->section_num >= NCA_FS_HEADER_COUNT || ctx->section_offset < sizeof(NcaHeader) || \
|
||||
ctx->section_type >= NcaFsSectionType_Invalid || ctx->encryption_type == NcaEncryptionType_Auto || ctx->encryption_type >= NcaEncryptionType_AesCtrEx || !data || !data_size || \
|
||||
(data_offset + data_size) > ctx->section_size || !out_block_size || !out_block_offset)
|
||||
ctx->hash_type < NcaHashType_HierarchicalSha256 || ctx->hash_type > NcaHashType_HierarchicalIntegrity || ctx->encryption_type == NcaEncryptionType_Auto || \
|
||||
ctx->encryption_type >= NcaEncryptionType_AesCtrEx || ctx->section_type >= NcaFsSectionType_Invalid || !data || !data_size || (data_offset + data_size) > ctx->section_size || \
|
||||
!out_block_size || !out_block_offset)
|
||||
{
|
||||
LOG_MSG("Invalid NCA FS section header parameters!");
|
||||
goto end;
|
||||
|
|
Loading…
Reference in a new issue