mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2026-09-16 20:04:15 +00:00
Add recursion guard for Wii U re-encryption: implement flag to prevent recursive calls during sector processing
This commit is contained in:
@@ -353,6 +353,7 @@ typedef struct aaruformat_context
|
||||
uint8_t *wiiu_encrypted_block_cache; ///< Cached re-encrypted 0x8000-byte physical sector
|
||||
uint64_t wiiu_cached_physical_sector; ///< Physical sector number of cached block
|
||||
bool wiiu_cache_valid; ///< Whether the encrypted block cache is valid
|
||||
bool wiiu_building_crypto_block; ///< True while gathering sectors for re-encryption (suppresses recursion)
|
||||
} aaruformat_context;
|
||||
|
||||
/** \struct DumpHardwareEntriesWithData
|
||||
|
||||
73
src/read.c
73
src/read.c
@@ -435,7 +435,8 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se
|
||||
}
|
||||
|
||||
// Wii U re-encryption: if stored decrypted, re-encrypt for caller
|
||||
if(*sector_status == SectorStatusUnencrypted && ctx->header.mediaType == WUOD)
|
||||
if(*sector_status == SectorStatusUnencrypted && ctx->header.mediaType == WUOD &&
|
||||
!ctx->wiiu_building_crypto_block)
|
||||
{
|
||||
if(!ctx->wiiu_encryption_initialized)
|
||||
{
|
||||
@@ -455,32 +456,42 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se
|
||||
|
||||
if(!ctx->wiiu_cache_valid || ctx->wiiu_cached_physical_sector != phys_sector)
|
||||
{
|
||||
// Build the 0x8000 block from the decompressed block cache
|
||||
uint64_t first_logical = phys_sector * WIIU_LOGICAL_PER_PHYSICAL;
|
||||
uint32_t sectors_in_block = block_header->length / block_header->sectorSize;
|
||||
uint64_t block_first = sector_address - offset;
|
||||
uint64_t first_logical = phys_sector * WIIU_LOGICAL_PER_PHYSICAL;
|
||||
|
||||
// Read all 16 logical sectors via aaruf_read_sector with recursion guard
|
||||
ctx->wiiu_building_crypto_block = true;
|
||||
|
||||
for(uint32_t s = 0; s < WIIU_LOGICAL_PER_PHYSICAL; s++)
|
||||
{
|
||||
uint64_t logical = first_logical + s;
|
||||
int64_t idx = (int64_t)(logical - block_first);
|
||||
|
||||
if(idx >= 0 && (uint32_t)idx < sectors_in_block)
|
||||
memcpy(ctx->wiiu_encrypted_block_cache + s * block_header->sectorSize,
|
||||
block + (uint32_t)idx * block_header->sectorSize, block_header->sectorSize);
|
||||
if(logical == sector_address)
|
||||
{
|
||||
// Current sector is already in data buffer
|
||||
memcpy(ctx->wiiu_encrypted_block_cache + s * (*length), data, *length);
|
||||
}
|
||||
else
|
||||
memset(ctx->wiiu_encrypted_block_cache + s * block_header->sectorSize, 0,
|
||||
block_header->sectorSize);
|
||||
{
|
||||
uint32_t s_len = *length;
|
||||
uint8_t s_status = 0;
|
||||
int32_t s_ret =
|
||||
aaruf_read_sector(context, logical, false,
|
||||
ctx->wiiu_encrypted_block_cache + s * s_len, &s_len, &s_status);
|
||||
|
||||
if(s_ret != AARUF_STATUS_OK)
|
||||
memset(ctx->wiiu_encrypted_block_cache + s * (*length), 0, *length);
|
||||
}
|
||||
}
|
||||
|
||||
ctx->wiiu_building_crypto_block = false;
|
||||
|
||||
wiiu_encrypt_physical_sector(part_key, ctx->wiiu_encrypted_block_cache,
|
||||
WIIU_CRYPTO_SECTOR_SIZE);
|
||||
ctx->wiiu_cached_physical_sector = phys_sector;
|
||||
ctx->wiiu_cache_valid = true;
|
||||
}
|
||||
|
||||
memcpy(data, ctx->wiiu_encrypted_block_cache + slice_index * block_header->sectorSize,
|
||||
block_header->sectorSize);
|
||||
memcpy(data, ctx->wiiu_encrypted_block_cache + slice_index * (*length), *length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,7 +698,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se
|
||||
}
|
||||
|
||||
// Wii U re-encryption: if stored decrypted, re-encrypt for caller
|
||||
if(*sector_status == SectorStatusUnencrypted && ctx->header.mediaType == WUOD)
|
||||
if(*sector_status == SectorStatusUnencrypted && ctx->header.mediaType == WUOD && !ctx->wiiu_building_crypto_block)
|
||||
{
|
||||
if(!ctx->wiiu_encryption_initialized)
|
||||
{
|
||||
@@ -707,31 +718,41 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se
|
||||
|
||||
if(!ctx->wiiu_cache_valid || ctx->wiiu_cached_physical_sector != phys_sector)
|
||||
{
|
||||
// Build the 0x8000 block from the decompressed block cache
|
||||
uint64_t first_logical = phys_sector * WIIU_LOGICAL_PER_PHYSICAL;
|
||||
uint32_t sectors_in_block = block_header->length / block_header->sectorSize;
|
||||
uint64_t block_first = sector_address - offset;
|
||||
uint64_t first_logical = phys_sector * WIIU_LOGICAL_PER_PHYSICAL;
|
||||
|
||||
// Read all 16 logical sectors via aaruf_read_sector with recursion guard
|
||||
ctx->wiiu_building_crypto_block = true;
|
||||
|
||||
for(uint32_t s = 0; s < WIIU_LOGICAL_PER_PHYSICAL; s++)
|
||||
{
|
||||
uint64_t logical = first_logical + s;
|
||||
int64_t idx = (int64_t)(logical - block_first);
|
||||
|
||||
if(idx >= 0 && (uint32_t)idx < sectors_in_block)
|
||||
memcpy(ctx->wiiu_encrypted_block_cache + s * block_header->sectorSize,
|
||||
block + (uint32_t)idx * block_header->sectorSize, block_header->sectorSize);
|
||||
if(logical == sector_address)
|
||||
{
|
||||
// Current sector is already in data buffer
|
||||
memcpy(ctx->wiiu_encrypted_block_cache + s * (*length), data, *length);
|
||||
}
|
||||
else
|
||||
memset(ctx->wiiu_encrypted_block_cache + s * block_header->sectorSize, 0,
|
||||
block_header->sectorSize);
|
||||
{
|
||||
uint32_t s_len = *length;
|
||||
uint8_t s_status = 0;
|
||||
int32_t s_ret =
|
||||
aaruf_read_sector(context, logical, false, ctx->wiiu_encrypted_block_cache + s * s_len,
|
||||
&s_len, &s_status);
|
||||
|
||||
if(s_ret != AARUF_STATUS_OK)
|
||||
memset(ctx->wiiu_encrypted_block_cache + s * (*length), 0, *length);
|
||||
}
|
||||
}
|
||||
|
||||
ctx->wiiu_building_crypto_block = false;
|
||||
|
||||
wiiu_encrypt_physical_sector(part_key, ctx->wiiu_encrypted_block_cache, WIIU_CRYPTO_SECTOR_SIZE);
|
||||
ctx->wiiu_cached_physical_sector = phys_sector;
|
||||
ctx->wiiu_cache_valid = true;
|
||||
}
|
||||
|
||||
memcpy(data, ctx->wiiu_encrypted_block_cache + slice_index * block_header->sectorSize,
|
||||
block_header->sectorSize);
|
||||
memcpy(data, ctx->wiiu_encrypted_block_cache + slice_index * (*length), *length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user