/// <summary> /// Creates a new managed transform instance, reading necessary /// setting values from the provided <see cref="ISymmetricAlgorithm" /> /// instance. /// </summary> /// <param name="algorithm"> /// A <see cref="ISymmetricAlgorithm" /> instance from which to take /// setting values. /// </param> /// <param name="rgbIv"> /// The initialization vector to use. /// </param> /// <param name="transformDirection"> /// The direction of the transform (encryption or decryption). /// </param> /// <param name="endianness"> /// The endianness convention for the algorithm. /// </param> protected ManagedTransformBase(ISymmetricAlgorithm algorithm, byte[] rgbIv, TransformDirection transformDirection, Endianness endianness) { Endianness = endianness; _bytesToWords = endianness == Endianness.Little ? (BytesToWords)Utils.BytesToWordsLittleEndian : Utils.BytesToWordsBigEndian; _writeWordsIntoBytes = endianness == Endianness.Little ? (WriteWordsIntoBytes)Utils.WriteWordsIntoBytesLittleEndian : Utils.WriteWordsIntoBytesBigEndian; PaddingMode = algorithm.Padding; BlockSizeBytes = algorithm.BlockSize >> 3; Mode = algorithm.ExtendedMode; NonceCombinationMode = algorithm.NonceCombinationMode; _registerShiftSize = algorithm.RegisterShiftSize; _feedbackValue = new byte[BlockSizeBytes]; _iv = new byte[BlockSizeBytes]; if (rgbIv != null) { rgbIv.CopyTo(_feedbackValue, 0); rgbIv.CopyTo(_iv, 0); if (Mode == ExtendedCipherMode.CTR) { switch (NonceCombinationMode) { case NonceCombinationMode.Concatenate: _counterSize = BlockSizeBytes - rgbIv.Length; _counter = new byte[_counterSize]; break; case NonceCombinationMode.Xor: _counterSize = BlockSizeBytes; _counter = new byte[_counterSize]; break; case NonceCombinationMode.Add: _counterSize = BlockSizeBytes; _counter = (byte[])_feedbackValue.Clone(); break; } _initial = true; } } _transformDirection = transformDirection; }