Exemple #1
0
        public static byte[] StreamToByteArray(ICrypToolStream stream)
        {
            byte[] buf = new byte[stream.Length];

            CStreamReader reader = stream.CreateReader();

            reader.WaitEof();
            reader.Seek(0, System.IO.SeekOrigin.Begin);
            reader.ReadFully(buf);
            reader.Close();

            return(buf);
        }
Exemple #2
0
        private void process(int action)
        {
            //Encrypt/Decrypt Stream
            try
            {
                if (InputStream == null || InputStream.Length == 0)
                {
                    GuiLogMessage("No input data, aborting now", NotificationLevel.Error);
                    return;
                }

                SymmetricAlgorithm p_alg = null;
                if (settings.CryptoAlgorithm == 1)
                {
                    p_alg = new RijndaelManaged();
                }
                else
                {
                    p_alg = new AesCryptoServiceProvider();
                }

                ConfigureAlg(p_alg);

                ICryptoTransform p_encryptor = null;
                switch (action)
                {
                case 0:
                    p_encryptor = p_alg.CreateEncryptor();
                    break;

                case 1:
                    p_encryptor = p_alg.CreateDecryptor();
                    break;
                }

                outputStreamWriter = new CStreamWriter();

                ICrypToolStream inputdata = InputStream;

                string mode = action == 0 ? "encryption" : "decryption";
                long   inbytes, outbytes;

                //GuiLogMessage("Starting " + mode + " [Keysize=" + p_alg.KeySize.ToString() + " Bits, Blocksize=" + p_alg.BlockSize.ToString() + " Bits]", NotificationLevel.Info);

                DateTime startTime = DateTime.Now;

                // special handling of OFB mode, as it's not available for AES in .Net
                if (settings.Mode == 3)    // OFB - bei OFB ist encrypt = decrypt, daher keine Fallunterscheidung
                {
                    if (action == 0)
                    {
                        inputdata = BlockCipherHelper.AppendPadding(InputStream, settings.padmap[settings.Padding], p_alg.BlockSize / 8);
                    }

                    ICryptoTransform encrypt = p_alg.CreateEncryptor(p_alg.Key, p_alg.IV);

                    byte[] IV = new byte[p_alg.IV.Length];
                    Array.Copy(p_alg.IV, IV, p_alg.IV.Length);
                    byte[] tmpInput   = BlockCipherHelper.StreamToByteArray(inputdata);
                    byte[] outputData = new byte[tmpInput.Length];

                    for (int pos = 0; pos <= tmpInput.Length - encrypt.InputBlockSize;)
                    {
                        int l = encrypt.TransformBlock(IV, 0, encrypt.InputBlockSize, outputData, pos);
                        for (int i = 0; i < l; i++)
                        {
                            IV[i] = outputData[pos + i];
                            outputData[pos + i] ^= tmpInput[pos + i];
                        }
                        pos += l;
                    }

                    int validBytes = (int)inputdata.Length;

                    if (action == 1)
                    {
                        validBytes = BlockCipherHelper.StripPadding(outputData, validBytes, settings.padmap[settings.Padding], p_alg.BlockSize / 8);
                    }

                    encrypt.Dispose();
                    outputStreamWriter.Write(outputData, 0, validBytes);
                    inbytes = inputdata.Length;
                }
                else if (settings.Mode == 4)
                {
                    if (action == 0)
                    {
                        inputdata = BlockCipherHelper.AppendPadding(InputStream, settings.padmap[settings.Padding], p_alg.BlockSize / 8);
                    }

                    byte[] tmpInput = BlockCipherHelper.StreamToByteArray(inputdata);

                    var cipher       = new AesEngine();
                    var eaxCipher    = new EaxBlockCipher(cipher);
                    var keyParameter = new KeyParameter(p_alg.Key);
                    var parameter    = new ParametersWithIV(keyParameter, p_alg.IV);
                    eaxCipher.Init((action == 0) ? true : false, parameter);

                    byte[] datOut = new byte[eaxCipher.GetOutputSize(tmpInput.Length)];
                    int    outOff = eaxCipher.ProcessBytes(tmpInput, 0, tmpInput.Length, datOut, 0);
                    outOff += eaxCipher.DoFinal(datOut, outOff);

                    int validBytes = (int)eaxCipher.GetOutputSize(tmpInput.Length);
                    if (action == 1)
                    {
                        validBytes = BlockCipherHelper.StripPadding(datOut, validBytes, settings.padmap[settings.Padding], p_alg.BlockSize / 8);
                    }
                    outputStreamWriter.Write(datOut, 0, validBytes);
                    inbytes = inputdata.Length;
                }
                else
                {
                    // append 1-0 padding (special handling, as it's not present in System.Security.Cryptography.PaddingMode)
                    if (action == 0 && settings.Padding == 5)
                    {
                        inputdata = BlockCipherHelper.AppendPadding(InputStream, BlockCipherHelper.PaddingType.OneZeros, p_alg.BlockSize / 8);
                    }

                    CStreamReader reader = inputdata.CreateReader();

                    p_crypto_stream = new CryptoStream(reader, p_encryptor, CryptoStreamMode.Read);
                    byte[] buffer = new byte[p_alg.BlockSize / 8];
                    int    bytesRead;
                    int    position = 0;

                    while ((bytesRead = p_crypto_stream.Read(buffer, 0, buffer.Length)) > 0 && !stop)
                    {
                        // remove 1-0 padding (special handling, as it's not present in System.Security.Cryptography.PaddingMode)
                        if (action == 1 && settings.Padding == 5 && reader.Position == reader.Length)
                        {
                            bytesRead = BlockCipherHelper.StripPadding(buffer, bytesRead, BlockCipherHelper.PaddingType.OneZeros, buffer.Length);
                        }

                        outputStreamWriter.Write(buffer, 0, bytesRead);

                        if ((int)(reader.Position * 100 / reader.Length) > position)
                        {
                            position = (int)(reader.Position * 100 / reader.Length);
                            ProgressChanged(reader.Position, reader.Length);
                        }
                    }

                    p_crypto_stream.Flush();
                    inbytes = reader.Length;
                }

                outbytes = outputStreamWriter.Length;

                DateTime stopTime = DateTime.Now;
                TimeSpan duration = stopTime - startTime;
                // (outputStream as CrypToolStream).FinishWrite();

                if (!stop)
                {
                    mode = action == 0 ? "Encryption" : "Decryption";
                    //GuiLogMessage(mode + " complete! (in: " + inbytes + " bytes, out: " + outbytes + " bytes)", NotificationLevel.Info);
                    //GuiLogMessage("Time used: " + duration.ToString(), NotificationLevel.Debug);
                    outputStreamWriter.Close();
                    OnPropertyChanged("OutputStream");
                }

                if (stop)
                {
                    outputStreamWriter.Close();
                    GuiLogMessage("Aborted!", NotificationLevel.Info);
                }
            }
            catch (CryptographicException cryptographicException)
            {
                // TODO: For an unknown reason p_crypto_stream cannot be closed after exception.
                // Trying so makes p_crypto_stream throw the same exception again. So in Dispose
                // the error messages will be doubled.
                // As a workaround we set p_crypto_stream to null here.
                p_crypto_stream = null;

                string msg = cryptographicException.Message;

                // Workaround for misleading german error message
                if (msg == "Die Zeichenabstände sind ungültig und können nicht entfernt werden.")
                {
                    msg = "Das Padding ist ungültig und kann nicht entfernt werden.";
                }

                GuiLogMessage(msg, NotificationLevel.Error);
            }
            catch (Exception exception)
            {
                GuiLogMessage(exception.Message, NotificationLevel.Error);
            }
            finally
            {
                ProgressChanged(1, 1);
            }
        }
Exemple #3
0
 public static ICrypToolStream AppendPadding(ICrypToolStream input, PaddingType paddingtype, int blocksize)
 {
     return(new CStreamWriter(AppendPadding(StreamToByteArray(input), paddingtype, blocksize)));
 }
Exemple #4
0
        /// <summary>
        /// Encrypts/Decrypts using OFB
        /// </summary>
        /// <param name="blockCipher"></param>
        /// <param name="cipherAction"></param>
        /// <param name="inputStream"></param>
        /// <param name="outputStream"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <param name="padding"></param>
        /// <param name="stop"></param>
        /// <param name="progressChanged"></param>
        /// <param name="lastInputBlock"></param>
        /// <param name="blocksize"></param>
        public static void ExecuteOFB(BlockCipher blockCipher,
                                      CipherAction cipherAction,
                                      ref ICrypToolStream inputStream,
                                      ref ICrypToolStream outputStream,
                                      byte[] key,
                                      byte[] iv,
                                      PaddingType padding,
                                      ref bool stop,
                                      ProgressChanged progressChanged,
                                      ref byte[] lastInputBlock,
                                      int blocksize = 8)
        {
            using (CStreamReader reader = inputStream.CreateReader())
            {
                using (CStreamWriter writer = new CStreamWriter())
                {
                    byte[] lastBlock = iv;
                    int    readcount = 0;

                    while (reader.Position < reader.Length && !stop)
                    {
                        //we always try to read a complete block
                        byte[] inputBlock = new byte[blocksize];
                        readcount = 0;
                        while ((readcount += reader.Read(inputBlock, readcount, blocksize - readcount)) < blocksize &&
                               reader.Position < reader.Length && !stop)
                        {
                            ;
                        }
                        if (stop)
                        {
                            return;
                        }

                        //Show progress in UI
                        progressChanged(reader.Position, reader.Length);

                        byte[] outputblock = null;
                        //we read a complete block
                        if (readcount == blocksize)
                        {
                            //Compute XOR with lastblock for OFB mode
                            if (cipherAction == CipherAction.Encrypt)
                            {
                                outputblock = blockCipher(lastBlock, key);
                                lastBlock   = outputblock;
                                outputblock = XOR(outputblock, inputBlock);
                            }
                            else
                            {
                                outputblock = blockCipher(lastBlock, key);
                                lastBlock   = outputblock;
                                outputblock = XOR(outputblock, inputBlock);
                            }
                        }
                        //we read an incomplete block, thus, we are at the end of the stream
                        else if (readcount > 0)
                        {
                            //Compute XOR with lastblock for CFB mode
                            if (cipherAction == CipherAction.Encrypt)
                            {
                                byte[] block = new byte[blocksize];
                                Array.Copy(inputBlock, 0, block, 0, readcount);
                                outputblock = blockCipher(lastBlock, key);
                                outputblock = XOR(outputblock, block);
                            }
                            else
                            {
                                byte[] block = new byte[blocksize];
                                Array.Copy(inputBlock, 0, block, 0, readcount);
                                outputblock = blockCipher(inputBlock, key);
                                outputblock = XOR(outputblock, lastBlock);
                            }
                        }

                        //check if it is the last block and we decrypt, thus, we have to remove the padding
                        if (reader.Position == reader.Length && cipherAction == CipherAction.Decrypt && padding != PaddingType.None)
                        {
                            int valid = StripPadding(outputblock, blocksize, padding, blocksize);
                            if (valid != blocksize)
                            {
                                byte[] newoutputblock = new byte[valid];
                                Array.Copy(outputblock, 0, newoutputblock, 0, valid);
                                outputblock = newoutputblock;
                            }
                            else if (valid == 0)
                            {
                                outputblock = null;
                            }
                        }

                        //if we crypted something, we output it
                        if (outputblock != null)
                        {
                            writer.Write(outputblock, 0, outputblock.Length);
                            //if we wrote to the stream, we memorize the last input block for the visualization
                            lastInputBlock = inputBlock;
                        }
                    }

                    writer.Flush();
                    outputStream = writer;
                }
            }
        }