public Aes128CtrStorage(IStorage baseStorage, byte[] key, byte[] counter, bool leaveOpen) : base(baseStorage, BlockSize, leaveOpen) { if (key == null) { throw new NullReferenceException(nameof(key)); } if (key.Length != BlockSize) { throw new ArgumentException(nameof(key), $"Key must be {BlockSize} bytes long"); } if (counter == null) { throw new NullReferenceException(nameof(counter)); } if (counter.Length != BlockSize) { throw new ArgumentException(nameof(counter), $"Counter must be {BlockSize} bytes long"); } // Make the stream seekable by remembering the initial counter value for (int i = 0; i < 8; i++) { _counterOffset |= (long)counter[0xF - i] << (4 + i * 8); } _decryptor = new Aes128CtrTransform(key, counter); Counter = _decryptor.Counter; }
/// <summary> /// Creates a new AES storage /// </summary> /// <param name="baseStorage">The input <see cref="IStorage"/>.</param> /// <param name="key">The decryption key.</param> /// <param name="counterOffset">Offset to add to the counter.</param> /// <param name="counterHi">The value of the upper 64 bits of the counter. Can be null.</param> /// <param name="leaveOpen"><see langword="true"/> to leave the storage open after the <see cref="Aes128CtrStorage"/> object is disposed; otherwise, <see langword="false"/>.</param> public Aes128CtrStorage(IStorage baseStorage, byte[] key, long counterOffset, byte[] counterHi, bool leaveOpen) : base(baseStorage, BlockSize, leaveOpen) { if (key == null) { throw new NullReferenceException(nameof(key)); } if (key.Length != BlockSize) { throw new ArgumentException(nameof(key), $"Key must be {BlockSize} bytes long"); } var initialCounter = new byte[BlockSize]; if (counterHi != null) { Array.Copy(counterHi, initialCounter, 8); } _counterOffset = counterOffset; _decryptor = new Aes128CtrTransform(key, initialCounter); Counter = _decryptor.Counter; }