/// <summary> /// Creates a new stream /// </summary> /// <param name="baseStream">The base stream</param> /// <param name="key">The decryption key</param> /// <param name="offset">Offset to start at in the input stream</param> /// <param name="length">The length of the created stream</param> /// <param name="counterOffset">Offset to add to the counter</param> /// <param name="ctrHi">The value of the upper 64 bits of the counter</param> public Aes128CtrStream(Stream baseStream, byte[] key, long offset, long length, long counterOffset, byte[] ctrHi = null) : base(baseStream, BlockSize, CryptChunkSize / BlockSize, offset) { var initialCounter = new byte[BlockSize]; if (ctrHi != null) { Array.Copy(ctrHi, initialCounter, 8); } _counterOffset = counterOffset; Length = length; _tempBuffer = new byte[CryptChunkSize]; _decryptor = new Aes128CtrTransform(key, initialCounter, CryptChunkSize); Counter = _decryptor.Counter; UpdateCounter(_counterOffset + base.Position); baseStream.Position = offset; }
/// <summary> /// Creates a new stream /// </summary> /// <param name="baseStream">The base stream</param> /// <param name="key">The decryption key</param> /// <param name="offset">Offset to start at in the input stream</param> /// <param name="length">The length of the created stream</param> /// <param name="counter">The initial counter</param> public Aes128CtrStream(Stream baseStream, byte[] key, long offset, long length, byte[] counter) : base(baseStream, BlockSize, 1, offset) { _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 = length; _tempBuffer = new byte[CryptChunkSize]; _decryptor = new Aes128CtrTransform(key, counter ?? new byte[0x10], CryptChunkSize); Counter = _decryptor.Counter; }