VolumeWiiCrypted: Store last decrypted offset instead of block number
This makes it unnecessary to reset m_last_decrypted_offset when changing partition.
This commit is contained in:
parent
651340826d
commit
5c46810a36
|
@ -31,7 +31,7 @@ namespace DiscIO
|
||||||
CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr<IBlobReader> reader, u64 _VolumeOffset,
|
CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr<IBlobReader> reader, u64 _VolumeOffset,
|
||||||
const unsigned char* _pVolumeKey)
|
const unsigned char* _pVolumeKey)
|
||||||
: m_pReader(std::move(reader)), m_AES_ctx(std::make_unique<mbedtls_aes_context>()),
|
: m_pReader(std::move(reader)), m_AES_ctx(std::make_unique<mbedtls_aes_context>()),
|
||||||
m_VolumeOffset(_VolumeOffset), m_dataOffset(0x20000), m_LastDecryptedBlockOffset(-1)
|
m_VolumeOffset(_VolumeOffset), m_dataOffset(0x20000), m_last_decrypted_block(-1)
|
||||||
{
|
{
|
||||||
_assert_(m_pReader);
|
_assert_(m_pReader);
|
||||||
|
|
||||||
|
@ -41,7 +41,6 @@ CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr<IBlobReader> reader, u64 _V
|
||||||
bool CVolumeWiiCrypted::ChangePartition(u64 offset)
|
bool CVolumeWiiCrypted::ChangePartition(u64 offset)
|
||||||
{
|
{
|
||||||
m_VolumeOffset = offset;
|
m_VolumeOffset = offset;
|
||||||
m_LastDecryptedBlockOffset = -1;
|
|
||||||
|
|
||||||
u8 volume_key[16];
|
u8 volume_key[16];
|
||||||
DiscIO::VolumeKeyForPartition(*m_pReader, offset, volume_key);
|
DiscIO::VolumeKeyForPartition(*m_pReader, offset, volume_key);
|
||||||
|
@ -61,25 +60,25 @@ bool CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer, bool de
|
||||||
std::vector<u8> read_buffer(BLOCK_TOTAL_SIZE);
|
std::vector<u8> read_buffer(BLOCK_TOTAL_SIZE);
|
||||||
while (_Length > 0)
|
while (_Length > 0)
|
||||||
{
|
{
|
||||||
// Calculate block offset
|
// Calculate offsets
|
||||||
u64 Block = _ReadOffset / BLOCK_DATA_SIZE;
|
u64 block_offset_on_disc =
|
||||||
u64 Offset = _ReadOffset % BLOCK_DATA_SIZE;
|
m_VolumeOffset + m_dataOffset + _ReadOffset / BLOCK_DATA_SIZE * BLOCK_TOTAL_SIZE;
|
||||||
|
u64 data_offset_in_block = _ReadOffset % BLOCK_DATA_SIZE;
|
||||||
|
|
||||||
if (m_LastDecryptedBlockOffset != Block)
|
if (m_last_decrypted_block != block_offset_on_disc)
|
||||||
{
|
{
|
||||||
// Read the current block
|
// Read the current block
|
||||||
if (!m_pReader->Read(m_VolumeOffset + m_dataOffset + Block * BLOCK_TOTAL_SIZE,
|
if (!m_pReader->Read(block_offset_on_disc, BLOCK_TOTAL_SIZE, read_buffer.data()))
|
||||||
BLOCK_TOTAL_SIZE, read_buffer.data()))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Decrypt the block's data.
|
// Decrypt the block's data.
|
||||||
// 0x3D0 - 0x3DF in m_pBuffer will be overwritten,
|
// 0x3D0 - 0x3DF in read_buffer will be overwritten,
|
||||||
// but that won't affect anything, because we won't
|
// but that won't affect anything, because we won't
|
||||||
// use the content of m_pBuffer anymore after this
|
// use the content of read_buffer anymore after this
|
||||||
mbedtls_aes_crypt_cbc(m_AES_ctx.get(), MBEDTLS_AES_DECRYPT, BLOCK_DATA_SIZE,
|
mbedtls_aes_crypt_cbc(m_AES_ctx.get(), MBEDTLS_AES_DECRYPT, BLOCK_DATA_SIZE,
|
||||||
&read_buffer[0x3D0], &read_buffer[BLOCK_HEADER_SIZE],
|
&read_buffer[0x3D0], &read_buffer[BLOCK_HEADER_SIZE],
|
||||||
m_LastDecryptedBlock);
|
m_last_decrypted_block_data);
|
||||||
m_LastDecryptedBlockOffset = Block;
|
m_last_decrypted_block = block_offset_on_disc;
|
||||||
|
|
||||||
// The only thing we currently use from the 0x000 - 0x3FF part
|
// The only thing we currently use from the 0x000 - 0x3FF part
|
||||||
// of the block is the IV (at 0x3D0), but it also contains SHA-1
|
// of the block is the IV (at 0x3D0), but it also contains SHA-1
|
||||||
|
@ -88,9 +87,9 @@ bool CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer, bool de
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the decrypted data
|
// Copy the decrypted data
|
||||||
u64 MaxSizeToCopy = BLOCK_DATA_SIZE - Offset;
|
u64 MaxSizeToCopy = BLOCK_DATA_SIZE - data_offset_in_block;
|
||||||
u64 CopySize = (_Length > MaxSizeToCopy) ? MaxSizeToCopy : _Length;
|
u64 CopySize = (_Length > MaxSizeToCopy) ? MaxSizeToCopy : _Length;
|
||||||
memcpy(_pBuffer, &m_LastDecryptedBlock[Offset], (size_t)CopySize);
|
memcpy(_pBuffer, &m_last_decrypted_block_data[data_offset_in_block], (size_t)CopySize);
|
||||||
|
|
||||||
// Update offsets
|
// Update offsets
|
||||||
_Length -= CopySize;
|
_Length -= CopySize;
|
||||||
|
|
|
@ -68,8 +68,8 @@ private:
|
||||||
u64 m_VolumeOffset;
|
u64 m_VolumeOffset;
|
||||||
u64 m_dataOffset;
|
u64 m_dataOffset;
|
||||||
|
|
||||||
mutable u64 m_LastDecryptedBlockOffset;
|
mutable u64 m_last_decrypted_block;
|
||||||
mutable unsigned char m_LastDecryptedBlock[BLOCK_DATA_SIZE];
|
mutable u8 m_last_decrypted_block_data[BLOCK_DATA_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue