示例#1
0
        public static void Encrypt(StreamCtx ctx, Stream instr, Stream outstr, StreamCipherMonitor monitor)
        {
            if (instr.Length <= 0)
            {
                return;
            }

            byte[] buffer   = new byte[ctx.BlockSize()];
            byte[] output   = new byte[ctx.BlockSize()];
            bool   ivInited = false;
            int    i        = 0;

            if (monitor != null)
            {
                monitor.Progress(0, instr.Length);
            }
            do
            {
                if (monitor != null)
                {
                    if (monitor.ShouldStop())
                    {
                        return;
                    }
                    monitor.Progress(instr.Position, instr.Length);
                }
                i = instr.Read(buffer, 0, ctx.BlockSize());
                if (i < 0)
                {
                    i = 0;
                }
                if ((i > 0) && (!ivInited))                // first block
                {
                    ivInited = true;
                    if (ctx.Mode == Mode.CBC)
                    {
                        Array.Copy(ctx.IV, 0, output, 0, output.Length);
                    }
                }
                if ((i <= 0) || (i < buffer.Length))                // lastBlock
                {
                    PrepareLastBuffer(buffer, i);
                    PrepareBuffer(ctx.Mode, buffer, output);
                    ctx.Ibc.Cipher(buffer, output);
                    outstr.Write(output, 0, output.Length);
                    break;
                }
                PrepareBuffer(ctx.Mode, buffer, output);
                ctx.Ibc.Cipher(buffer, output);
                outstr.Write(output, 0, output.Length);
            } while(true);
            outstr.Flush();
            if (monitor != null)
            {
                if (!monitor.ShouldStop())
                {
                    monitor.Progress(instr.Length, instr.Length);
                }
            }
        }
示例#2
0
        public static void Decrypt(StreamCtx ctx, Stream instr, Stream outstr, StreamCipherMonitor monitor)
        {
            // in this method we fail silently

            if (instr.Length <= 0)
            {
                return;
            }
            byte[] buffer   = new byte[ctx.BlockSize()];
            byte[] output   = new byte[ctx.BlockSize()];
            int    i        = 0;
            bool   ivInited = false;

            byte[] iv = new byte[ctx.BlockSize()];
            // to delay the output, required because we do not rely in
            // instr.Length to find the end of stream
            bool lastInited = false;

            byte[] last = new byte[ctx.BlockSize()];
            if (monitor != null)
            {
                monitor.Progress(0, instr.Length);
            }
            do
            {
                if (monitor != null)
                {
                    if (monitor.ShouldStop())
                    {
                        return;
                    }
                    monitor.Progress(instr.Position, instr.Length);
                }
                i = instr.Read(buffer, 0, buffer.Length);
                if (i < 0)
                {
                    i = 0;
                }
                // must be a multiple of ctx.blockSize
                if ((i > 0) && (i != buffer.Length))
                {
                    return;                                                 //throw new Exception();
                }
                if ((i > 0) && (!ivInited))
                {
                    ivInited = true;
                    if (ctx.Mode == Mode.CBC)
                    {
                        Array.Copy(ctx.IV, 0, iv, 0, ctx.IV.Length);
                    }
                }
                if (i <= 0)                //lastblock
                {
                    // buffer has no data
                    if (!lastInited)
                    {
                        return;                                 // throw new Exception();
                    }
                    Array.Copy(last, output, output.Length);
                    // remove padd data
                    int k = (int)output[output.Length - 1];
                    if (k > output.Length)
                    {
                        return;
                    }
                    outstr.Write(output, 0, output.Length - k);
                    break;
                }
                ctx.Ibc.InvCipher(buffer, output);
                if (ctx.Mode == Mode.CBC)
                {
                    PrepareBuffer(ctx.Mode, output, iv);
                    Array.Copy(buffer, iv, buffer.Length);
                }
                //delay output
                if (!lastInited)
                {
                    Array.Copy(output, last, output.Length);
                    lastInited = true;
                }
                else
                {
                    outstr.Write(last, 0, last.Length);
                    Array.Copy(output, last, output.Length);
                }
            } while(true);
            outstr.Flush();
            if (monitor != null)
            {
                if (!monitor.ShouldStop())
                {
                    monitor.Progress(instr.Length, instr.Length);
                }
            }
        }