private int EncryptData(byte[] inputBuffer, int inputOffset, int inputCount, ref byte[] outputBuffer,
                                int outputOffset, PaddingMode paddingMode, bool final)
        {
            if (inputBuffer.Length < (inputOffset + inputCount))
            {
                throw new CryptographicException();
            }

            int inputBlockSize      = InputBlockSize;
            int blockSizeBytes      = BlockSizeBytes;
            ExtendedCipherMode mode = Mode;
            int partialBlockSize    = inputCount % inputBlockSize;
            int paddingSizeRequired = 0;

            byte[] data;
            if (final)
            {
                switch (paddingMode)
                {
                case PaddingMode.None:
                    if (partialBlockSize != 0 & !Utils.IsStreamMode(mode))
                    {
                        throw new CryptographicException();
                    }
                    break;

                case PaddingMode.PKCS7:
                    paddingSizeRequired = inputBlockSize - partialBlockSize;
                    break;

                case PaddingMode.Zeros:
                    if (partialBlockSize != 0)
                    {
                        paddingSizeRequired = inputBlockSize - partialBlockSize;
                    }
                    break;

                case PaddingMode.ANSIX923:
                    paddingSizeRequired = inputBlockSize - partialBlockSize;
                    break;

                case PaddingMode.ISO10126:
                    paddingSizeRequired = inputBlockSize - partialBlockSize;
                    break;
                }

                if (paddingSizeRequired != 0)
                {
                    data = new byte[paddingSizeRequired];
                    switch (paddingMode)
                    {
                    case PaddingMode.PKCS7:
                        int index = 0;
                        while (index < paddingSizeRequired)
                        {
                            data[index] = (byte)paddingSizeRequired;
                            index++;
                        }
                        break;

                    case PaddingMode.ANSIX923:
                        data[paddingSizeRequired - 1] = (byte)paddingSizeRequired;
                        break;

                    case PaddingMode.ISO10126:
                        Utils.RandomNumberGeneratorSingleton.GetBytes(data);
                        data[paddingSizeRequired - 1] = (byte)paddingSizeRequired;
                        break;
                    }
                    var tempBuffer = new byte[inputCount + paddingSizeRequired];
                    Array.Copy(inputBuffer, 0, tempBuffer, 0, inputCount);
                    data.CopyTo(tempBuffer, inputCount);
                    inputBuffer = tempBuffer;
                }
            }
            if (outputBuffer == null)
            {
                outputBuffer = new byte[inputCount + paddingSizeRequired];
                outputOffset = 0;
            }
            else if ((outputBuffer.Length - outputOffset) < (inputCount + paddingSizeRequired))
            {
                throw new CryptographicException();
            }

            int byteCount = 0;
            var tempState = new byte[blockSizeBytes];
            int count     = blockSizeBytes;

            if (mode == ExtendedCipherMode.CFB)
            {
                count = _registerShiftSize == 0 ? 1 : _registerShiftSize;
            }

            while (byteCount < inputCount + paddingSizeRequired)
            {
                var block       = new byte[blockSizeBytes];
                int bytesToCopy = count;
                if (blockSizeBytes + inputOffset > inputBuffer.Length)
                {
                    bytesToCopy = inputBuffer.Length - inputOffset;
                }
                Array.Copy(inputBuffer, inputOffset, block, 0, bytesToCopy);

                switch (mode)
                {
                case ExtendedCipherMode.ECB:
                    EncryptBlock(block);
                    break;

                case ExtendedCipherMode.CBC:
                    for (int i = 0; i < blockSizeBytes; i++)
                    {
                        block[i] ^= _feedbackValue[i];
                    }
                    EncryptBlock(block);
                    block.CopyTo(_feedbackValue, 0);
                    break;

                case ExtendedCipherMode.CFB:
                    Array.Copy(_feedbackValue, count, tempState, 0, blockSizeBytes - count);
                    EncryptBlock(_feedbackValue);
                    for (int i = 0; i < count; i++)
                    {
                        _feedbackValue[i] ^= block[i];
                    }
                    Array.Copy(_feedbackValue, 0, block, 0, count);
                    tempState.CopyTo(_feedbackValue, 0);
                    Array.Copy(block, 0, _feedbackValue, blockSizeBytes - count, count);
                    break;

                case ExtendedCipherMode.OFB:
                    Array.Copy(_feedbackValue, count, tempState, 0, blockSizeBytes - count);
                    EncryptBlock(_feedbackValue);
                    for (int i = 0; i < count; i++)
                    {
                        block[i] ^= _feedbackValue[i];
                    }
                    Array.Copy(_feedbackValue, 0, _feedbackValue, blockSizeBytes - count, count);
                    Array.Copy(tempState, 0, _feedbackValue, 0, blockSizeBytes - count);
                    break;

                case ExtendedCipherMode.CTS:
                    throw new NotImplementedException();

                case ExtendedCipherMode.CTR:
                    if (_initial)
                    {
                        _initial = false;
                    }
                    else
                    {
                        IncrementCounter();
                    }
                    switch (NonceCombinationMode)
                    {
                    case NonceCombinationMode.Concatenate:
                        _iv.CopyTo(_feedbackValue, 0);
                        _counter.CopyTo(_feedbackValue, blockSizeBytes - _counterSize);
                        break;

                    case NonceCombinationMode.Add:
                        _counter.CopyTo(_feedbackValue, 0);
                        break;

                    case NonceCombinationMode.Xor:
                        _iv.CopyTo(_feedbackValue, 0);
                        for (int index = 0; index < _counterSize; index++)
                        {
                            _feedbackValue[blockSizeBytes - _counterSize + index] ^= _counter[index];
                        }
                        break;
                    }
                    EncryptBlock(_feedbackValue);
                    for (int i = 0; i < blockSizeBytes; i++)
                    {
                        block[i] ^= _feedbackValue[i];
                    }
                    break;
                }

                if (outputOffset + count > outputBuffer.Length)
                {
                    count = outputBuffer.Length - outputOffset;
                }
                Array.Copy(block, 0, outputBuffer, outputOffset, count);

                byteCount    += count;
                inputOffset  += count;
                outputOffset += count;
            }

            if (Utils.IsStreamMode(mode) && outputBuffer.Length > inputCount && paddingMode == PaddingMode.None)
            {
                var result = new byte[inputCount];
                Array.Copy(outputBuffer, 0, result, 0, inputCount);
                outputBuffer = result;
            }

            return(inputCount);
        }
Exemplo n.º 2
0
 static internal bool IsStreamMode(ExtendedCipherMode mode)
 {
     return(mode == ExtendedCipherMode.CFB || mode == ExtendedCipherMode.OFB || mode == ExtendedCipherMode.CTR);
 }
Exemplo n.º 3
0
 internal static ICryptoTransform NewEncryptor(ISymmetricAlgorithm algorithm, Type type, byte[] rgbKey, ExtendedCipherMode mode, byte[] rgbIv, TransformDirection encryptDirection)
 {
     if (rgbKey == null)
     {
         rgbKey = algorithm.GenerateNonWeakKey();
     }
     if ((mode != ExtendedCipherMode.ECB) && (rgbIv == null))
     {
         rgbIv = new byte[algorithm.BlockSize / 8];
         RandomNumberGeneratorSingleton.GetBytes(rgbIv);
     }
     ConstructorInfo constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null,
                                                       new[] { typeof(ISymmetricAlgorithm), typeof(byte[]), typeof(byte[]),
                                                               typeof(TransformDirection)}, null);
     return (ICryptoTransform)constructor.Invoke(new object[] {algorithm, rgbKey, rgbIv, encryptDirection});
     //return (ICryptoTransform)Activator.CreateInstance(type, BindingFlags.NonPublic, null, new object[] { algorithm, rgbKey, rgbIv, encryptDirection }, null);
 }
Exemplo n.º 4
0
        static internal ICryptoTransform NewEncryptor(ISymmetricAlgorithm algorithm, Type type, byte[] rgbKey, ExtendedCipherMode mode, byte[] rgbIv, TransformDirection encryptDirection)
        {
            if (rgbKey == null)
            {
                rgbKey = algorithm.GenerateNonWeakKey();
            }
            if ((mode != ExtendedCipherMode.ECB) && (rgbIv == null))
            {
                rgbIv = new byte[algorithm.BlockSize / 8];
                RandomNumberGeneratorSingleton.GetBytes(rgbIv);
            }
            ConstructorInfo constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null,
                                                              new[] { typeof(ISymmetricAlgorithm), typeof(byte[]), typeof(byte[]),
                                                                      typeof(TransformDirection) }, null);

            return((ICryptoTransform)constructor.Invoke(new object[] { algorithm, rgbKey, rgbIv, encryptDirection }));
            //return (ICryptoTransform)Activator.CreateInstance(type, BindingFlags.NonPublic, null, new object[] { algorithm, rgbKey, rgbIv, encryptDirection }, null);
        }
Exemplo n.º 5
0
 internal static bool IsStreamMode(ExtendedCipherMode mode)
 {
     return mode == ExtendedCipherMode.CFB || mode == ExtendedCipherMode.OFB || mode == ExtendedCipherMode.CTR;
 }