From 3d8d3992eb5c79e55ec1208f6fb40ccd311617d5 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Fri, 31 Aug 2018 17:53:57 -0500 Subject: [PATCH] Make certain AES streams seekable Make AES streams where the initial counter is supplied seekable by storing the initial counter value --- LibHac/Aes128CtrStream.cs | 18 ++++++++++++++---- LibHac/Streams/RandomAccessSectorStream.cs | 5 ++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/LibHac/Aes128CtrStream.cs b/LibHac/Aes128CtrStream.cs index b1d1073d..333c473c 100644 --- a/LibHac/Aes128CtrStream.cs +++ b/LibHac/Aes128CtrStream.cs @@ -29,11 +29,21 @@ namespace LibHac /// /// The base stream /// The decryption key - /// The intial counter + /// The initial counter public Aes128CtrStream(Stream baseStream, byte[] key, byte[] counter) : base(baseStream, BlockSize) { _counterOffset = 0; + + // Make the stream seekable by remembering the initial counter value + if (counter != null) + { + for (int i = 0; i < 8; i++) + { + _counterOffset |= (long)counter[0xF - i] << (4 + i * 8); + } + } + Length = baseStream.Length; _tempBuffer = new byte[CryptChunkSize]; @@ -70,11 +80,11 @@ namespace LibHac private void UpdateCounter(long offset) { - offset >>= 4; + ulong off = (ulong)offset >> 4; for (uint j = 0; j < 0x8; j++) { - Counter[0x10 - j - 1] = (byte)(offset & 0xFF); - offset >>= 8; + Counter[0x10 - j - 1] = (byte)(off & 0xFF); + off >>= 8; } } diff --git a/LibHac/Streams/RandomAccessSectorStream.cs b/LibHac/Streams/RandomAccessSectorStream.cs index 50332454..abd257ac 100644 --- a/LibHac/Streams/RandomAccessSectorStream.cs +++ b/LibHac/Streams/RandomAccessSectorStream.cs @@ -31,7 +31,10 @@ namespace LibHac.Streams _currentSector = sectorNum; long startPos = sectorNum * _bufferSize; - _baseStream.Position = startPos; + if (_baseStream.Position != startPos) + { + _baseStream.Position = startPos; + } _readBytes = _baseStream.Read(_buffer, 0, _bufferSize); }