示例#1
0
        public void GetResetHeadAtCapacityTest()
        {
            // arrange
            ByteCircularBuffer target;
            byte expected;
            byte actual;
            int  expectedHead;

            target = new ByteCircularBuffer(3);

            expected     = 3;
            expectedHead = 0;

            target.Put(1);
            target.Put(2);
            target.Put(3);

            target.Get();
            target.Get();

            // act
            actual = target.Get();

            // assert
            actual.Should().
            Be(expected);
            target.Head.Should().
            Be(expectedHead);
        }
示例#2
0
        public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
        {
            Debug.Assert(_encCircularBuffer != null, "_encCircularBuffer != null");

            _encCircularBuffer.Put(buf, 0, length);
            outlength = 0;
            Logging.Debug("---Start Encryption");
            if (!_encryptSaltSent)
            {
                _encryptSaltSent = true;
                // Generate salt
                byte[] saltBytes = new byte[saltLen];
                randBytes(saltBytes, saltLen);
                InitCipher(saltBytes, true, false);
                Array.Copy(saltBytes, 0, outbuf, 0, saltLen);
                outlength = saltLen;
                Logging.Debug($"_encryptSaltSent outlength {outlength}");
            }

            if (!_tcpRequestSent)
            {
                _tcpRequestSent = true;
                // The first TCP request
                int encAddrBufLength;

                byte[] encAddrBufBytes = new byte[AddrBufLength + tagLen * 2 + CHUNK_LEN_BYTES];
                byte[] addrBytes       = _encCircularBuffer.Get(AddrBufLength);
                ChunkEncrypt(addrBytes, AddrBufLength, encAddrBufBytes, out encAddrBufLength);
                Debug.Assert(encAddrBufLength == AddrBufLength + tagLen * 2 + CHUNK_LEN_BYTES);
                Array.Copy(encAddrBufBytes, 0, outbuf, outlength, encAddrBufLength);
                outlength += encAddrBufLength;
                Logging.Debug($"_tcpRequestSent outlength {outlength}");
            }

            // handle other chunks
            while (true)
            {
                uint bufSize = (uint)_encCircularBuffer.Size;
                if (bufSize <= 0)
                {
                    return;
                }
                var    chunklength = (int)Math.Min(bufSize, MaxChunkSize);
                byte[] chunkBytes  = _encCircularBuffer.Get(chunklength);
                int    encChunkLength;
                byte[] encChunkBytes = new byte[chunklength + tagLen * 2 + CHUNK_LEN_BYTES];
                ChunkEncrypt(chunkBytes, chunklength, encChunkBytes, out encChunkLength);
                Debug.Assert(encChunkLength == chunklength + tagLen * 2 + CHUNK_LEN_BYTES);
                PerfByteCopy(encChunkBytes, 0, outbuf, outlength, encChunkLength);
                outlength += encChunkLength;
                Logging.Debug("chunks enc outlength " + outlength);
                bufSize = (uint)_encCircularBuffer.Size;
                if (bufSize <= 0)
                {
                    Logging.Debug("No more data to encrypt, leaving");
                    return;
                }
            }
        }
        public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
        {
            int cipherOffset = 0;

            Debug.Assert(_encCircularBuffer != null, "_encCircularBuffer != null");
            _encCircularBuffer.Put(buf, 0, length);
            if (!_encryptIVSent)
            {
                // Generate IV
                byte[] ivBytes = new byte[ivLen];
                randBytes(ivBytes, ivLen);
                initCipher(ivBytes, true);

                Array.Copy(ivBytes, 0, outbuf, 0, ivLen);
                cipherOffset   = ivLen;
                _encryptIVSent = true;
            }
            int size = _encCircularBuffer.Size;

            byte[] plain  = _encCircularBuffer.Get(size);
            byte[] cipher = new byte[size];
            cipherUpdate(true, size, plain, cipher);
            Buffer.BlockCopy(cipher, 0, outbuf, cipherOffset, size);
            outlength = size + cipherOffset;
        }
        public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
        {
            //none rc4
            if (length == 0)
            {
                outlength = 0;
                return;
            }

            var cipherOffset = 0;

            _encCircularBuffer.Put(buf, 0, length);
            if (!_encryptIVSent)
            {
                InitCipher(_iv, true);
                Array.Copy(_iv, 0, outbuf, 0, ivLen);
                cipherOffset   = ivLen;
                _encryptIVSent = true;
            }
            var size   = _encCircularBuffer.Size;
            var plain  = _encCircularBuffer.Get(size);
            var cipher = new byte[size];

            CipherUpdate(true, size, plain, cipher);
            Buffer.BlockCopy(cipher, 0, outbuf, cipherOffset, size);
            outlength = size + cipherOffset;
        }
示例#5
0
        public void GetEmptyExceptionTest()
        {
            // arrange
            ByteCircularBuffer target;

            target = new ByteCircularBuffer(10);
            target.Put(1);
            target.Put(2);
            target.Put(3);
            target.Get();
            target.Get();
            target.Get();

            // act & assert
            Assert.That(() => target.Get(), Throws.TypeOf <InvalidOperationException>());
        }
示例#6
0
        public void GetWithArrayTest()
        {
            // arrange
            ByteCircularBuffer target;
            int expectedSize;
            int expectedHead;
            int expectedTail;
            int expectedElements;
            int actualElements;

            byte[] expected;
            byte[] actual;

            target = new ByteCircularBuffer(10);

            expected = new byte[]
            {
                1,
                2
            };
            expectedHead     = 2;
            expectedSize     = 1;
            expectedTail     = 3;
            expectedElements = 2;

            actual = new byte[expectedElements];

            target.Put(1);
            target.Put(2);
            target.Put(3);

            // act
            actualElements = target.Get(actual);

            // assert
            actualElements.Should().
            Be(expectedElements);
            actual.Should().
            Equal(expected);
            target.Contains(1).
            Should().
            BeFalse();
            target.Contains(2).
            Should().
            BeFalse();
            target.Contains(3).
            Should().
            BeTrue();
            target.Head.Should().
            Be(expectedHead);
            target.Tail.Should().
            Be(expectedTail);
            target.Size.Should().
            Be(expectedSize);
        }
示例#7
0
        public void GetNextTest()
        {
            // arrange
            ByteCircularBuffer target;
            byte expected;
            byte actual;

            target = new ByteCircularBuffer(10);
            target.Put(1);
            target.Put(2);
            target.Put(3);
            target.Get();

            expected = 2;

            // act
            actual = target.Get();

            // assert
            actual.Should().
            Be(expected);
        }
示例#8
0
        public void GetTest()
        {
            // arrange
            ByteCircularBuffer target;
            int  expectedSize;
            int  expectedHead;
            int  expectedTail;
            byte expected;
            byte actual;

            target = new ByteCircularBuffer(10);

            expected     = 1;
            expectedHead = 1;
            expectedSize = 2;
            expectedTail = 3;

            target.Put(1);
            target.Put(2);
            target.Put(3);

            // act
            actual = target.Get();

            // assert
            actual.Should().
            Be(expected);
            target.Contains(1).
            Should().
            BeFalse();
            target.Contains(2).
            Should().
            BeTrue();
            target.Contains(3).
            Should().
            BeTrue();
            target.Head.Should().
            Be(expectedHead);
            target.Tail.Should().
            Be(expectedTail);
            target.Size.Should().
            Be(expectedSize);
        }
示例#9
0
        public void ContainsAfterGetTest()
        {
            // arrange
            ByteCircularBuffer target;
            bool actual;

            target = new ByteCircularBuffer(10);
            target.Put(1);
            target.Put(2);
            target.Put(3);

            target.Get();

            // act
            actual = target.Contains(1);

            // assert
            actual.Should().
            BeFalse();
        }
 public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
 {
     Debug.Assert(_decCircularBuffer != null, "_circularBuffer != null");
     _decCircularBuffer.Put(buf, 0, length);
     if (!_decryptIVReceived)
     {
         if (_decCircularBuffer.Size <= ivLen)
         {
             // we need more data
             outlength = 0;
             return;
         }
         // start decryption
         _decryptIVReceived = true;
         byte[] iv = _decCircularBuffer.Get(ivLen);
         initCipher(iv, false);
     }
     byte[] cipher = _decCircularBuffer.ToArray();
     cipherUpdate(false, cipher.Length, cipher, outbuf);
     _decCircularBuffer.Clear();
     outlength = cipher.Length;
     // done the decryption
 }
        public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
        {
            _decCircularBuffer.Put(buf, 0, length);
            if (!_decryptIVReceived)
            {
                if (_decCircularBuffer.Size <= ivLen)
                {
                    // we need more data
                    outlength = 0;
                    return;
                }
                // start decryption
                _decryptIVReceived = true;
                var iv = ivLen == 0 ? new byte[0] : _decCircularBuffer.Get(ivLen); //none rc4
                InitCipher(iv, false);
            }
            var cipher = _decCircularBuffer.ToArray();

            CipherUpdate(false, cipher.Length, cipher, outbuf);
            // move pointer only
            _decCircularBuffer.Skip(_decCircularBuffer.Size);
            outlength = cipher.Length;
            // done the decryption
        }
示例#12
0
        public void EmptyBufferTest()
        {
            // arrange
            ByteCircularBuffer target;

            byte[] expected;
            byte[] actual;

            expected = this.GenerateRandomData(100);

            target = new ByteCircularBuffer(expected.Length);
            target.Put(expected);

            actual = new byte[target.Size];

            // act
            target.Get(actual);

            // assert
            actual.Should().
            Equal(expected);
            target.Size.Should().
            Be(0);
        }
示例#13
0
        public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
        {
            Debug.Assert(_decCircularBuffer != null, "_decCircularBuffer != null");
            int bufSize;

            outlength = 0;
            // drop all into buffer
            _decCircularBuffer.Put(buf, 0, length);

            Logging.Debug("---Start Decryption");
            if (!_decryptSaltReceived)
            {
                bufSize = _decCircularBuffer.Size;
                // check if we get the leading salt
                if (bufSize <= saltLen)
                {
                    // need more
                    return;
                }
                _decryptSaltReceived = true;
                byte[] salt = _decCircularBuffer.Get(saltLen);
                InitCipher(salt, false, false);
                Logging.Debug("get salt len " + saltLen);
            }

            // handle chunks
            while (true)
            {
                bufSize = _decCircularBuffer.Size;
                // check if we have any data
                if (bufSize <= 0)
                {
                    Logging.Debug("No data in _decCircularBuffer");
                    return;
                }

                // first get chunk length
                if (bufSize <= CHUNK_LEN_BYTES + tagLen)
                {
                    // so we only have chunk length and its tag?
                    return;
                }

                #region Chunk Decryption

                byte[] encLenBytes       = _decCircularBuffer.Peek(CHUNK_LEN_BYTES + tagLen);
                uint   decChunkLenLength = 0;
                byte[] decChunkLenBytes  = new byte[CHUNK_LEN_BYTES];
                // try to dec chunk len
                cipherDecrypt(encLenBytes, CHUNK_LEN_BYTES + (uint)tagLen, decChunkLenBytes, ref decChunkLenLength);
                Debug.Assert(decChunkLenLength == CHUNK_LEN_BYTES);
                // finally we get the real chunk len
                ushort chunkLen = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(decChunkLenBytes, 0));
                if (chunkLen > CHUNK_LEN_MASK)
                {
                    // we get invalid chunk
                    Logging.Error($"Invalid chunk length: {chunkLen}");
                    throw new CryptoErrorException();
                }
                Logging.Debug("Get the real chunk len:" + chunkLen);
                bufSize = _decCircularBuffer.Size;
                if (bufSize < CHUNK_LEN_BYTES + tagLen /* we haven't remove them */ + chunkLen + tagLen)
                {
                    Logging.Debug("No more data to decrypt one chunk");
                    return;
                }
                IncrementNonce(false);

                // we have enough data to decrypt one chunk
                // drop chunk len and its tag from buffer
                _decCircularBuffer.Skip(CHUNK_LEN_BYTES + tagLen);
                byte[] encChunkBytes = _decCircularBuffer.Get(chunkLen + tagLen);
                byte[] decChunkBytes = new byte[chunkLen];
                uint   decChunkLen   = 0;
                cipherDecrypt(encChunkBytes, chunkLen + (uint)tagLen, decChunkBytes, ref decChunkLen);
                Debug.Assert(decChunkLen == chunkLen);
                IncrementNonce(false);

                #endregion

                // output to outbuf
                Buffer.BlockCopy(decChunkBytes, 0, outbuf, outlength, (int)decChunkLen);
                outlength += (int)decChunkLen;
                Logging.Debug("aead dec outlength " + outlength);
                if (outlength + 100 > TCPHandler.BufferSize)
                {
                    Logging.Debug("dec outbuf almost full, giving up");
                    return;
                }
                bufSize = _decCircularBuffer.Size;
                // check if we already done all of them
                if (bufSize <= 0)
                {
                    Logging.Debug("No data in _decCircularBuffer, already all done");
                    return;
                }
            }
        }
        public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
        {
            Debug.Assert(_encCircularBuffer != null, "_encCircularBuffer != null");

            _encCircularBuffer.Put(buf, 0, length);
            outlength = 0;
            logger.Trace("---Start Encryption");
            if (!_encryptSaltSent)
            {
                _encryptSaltSent = true;
                // Generate salt
                byte[] saltBytes = new byte[saltLen];
                randBytes(saltBytes, saltLen);
                InitCipher(saltBytes, true, false);
                Array.Copy(saltBytes, 0, outbuf, 0, saltLen);
                outlength = saltLen;
                logger.Trace($"_encryptSaltSent outlength {outlength}");
            }

            if (!_tcpRequestSent)
            {
                _tcpRequestSent = true;
                // The first TCP request
                int    encAddrBufLength;
                byte[] encAddrBufBytes = new byte[AddrBufLength + tagLen * 2 + CHUNK_LEN_BYTES];
                byte[] addrBytes       = _encCircularBuffer.Get(AddrBufLength);
                ChunkEncrypt(addrBytes, AddrBufLength, encAddrBufBytes, out encAddrBufLength);
                Debug.Assert(encAddrBufLength == AddrBufLength + tagLen * 2 + CHUNK_LEN_BYTES);
                Array.Copy(encAddrBufBytes, 0, outbuf, outlength, encAddrBufLength);
                outlength += encAddrBufLength;
                logger.Trace($"_tcpRequestSent outlength {outlength}");
            }

            // handle other chunks
            while (true)
            {
                uint bufSize = (uint)_encCircularBuffer.Size;
                if (bufSize <= 0)
                {
                    return;
                }
                var    chunklength = (int)Math.Min(bufSize, CHUNK_LEN_MASK);
                byte[] chunkBytes  = _encCircularBuffer.Get(chunklength);
                int    encChunkLength;
                byte[] encChunkBytes = new byte[chunklength + tagLen * 2 + CHUNK_LEN_BYTES];
                ChunkEncrypt(chunkBytes, chunklength, encChunkBytes, out encChunkLength);
                Debug.Assert(encChunkLength == chunklength + tagLen * 2 + CHUNK_LEN_BYTES);
                Buffer.BlockCopy(encChunkBytes, 0, outbuf, outlength, encChunkLength);
                outlength += encChunkLength;
                logger.Trace("chunks enc outlength " + outlength);
                // check if we have enough space for outbuf
                if (outlength + TCPHandler.ChunkOverheadSize > TCPHandler.BufferSize)
                {
                    logger.Trace("enc outbuf almost full, giving up");
                    return;
                }
                bufSize = (uint)_encCircularBuffer.Size;
                if (bufSize <= 0)
                {
                    logger.Trace("No more data to encrypt, leaving");
                    return;
                }
            }
        }
示例#15
0
        public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
        {
            Debug.Assert(_encCircularBuffer != null, "_encCircularBuffer != null");

            _encCircularBuffer.Put(buf, 0, length);
            outlength = 0;
            Logging.Debug("---Start Encryption");
            if (!_encryptSaltSent)
            {
                _encryptSaltSent = true;
                // Generate salt
                byte[] saltBytes = new byte[saltLen];
                randBytes(saltBytes, saltLen);
                InitCipher(saltBytes, true, false);
                Array.Copy(saltBytes, 0, outbuf, 0, saltLen);
                outlength = saltLen;
                Logging.Debug($"_encryptSaltSent outlength {outlength}");
            }

            if (!_tcpRequestSent)
            {
                _tcpRequestSent = true;
                // The first TCP request
                int encAddrBufLength;

                byte[] garbage = GetGarbage(AddrBufLength, true);
                Logging.Debug("garbage len: " + garbage.Length);

                byte[] encAddrBufBytes = new byte[garbage.Length + AddrBufLength + tagLen * 2 + CHUNK_LEN_BYTES];
                byte[] addrBytes       = _encCircularBuffer.Get(AddrBufLength);
                byte[] addrWithGarbage = new byte[AddrBufLength + garbage.Length];
                PerfByteCopy(garbage, 0, addrWithGarbage, 0, garbage.Length);
                PerfByteCopy(addrBytes, 0, addrWithGarbage, garbage.Length, AddrBufLength);
                ChunkEncrypt(addrWithGarbage, AddrBufLength + garbage.Length, encAddrBufBytes, out encAddrBufLength);
                Debug.Assert(encAddrBufLength == garbage.Length + AddrBufLength + tagLen * 2 + CHUNK_LEN_BYTES);
                Array.Copy(encAddrBufBytes, 0, outbuf, outlength, encAddrBufLength);
                outlength += encAddrBufLength;
                Logging.Debug($"_tcpRequestSent outlength {outlength}");
            }

            // handle other chunks
            while (true)
            {
                uint bufSize = (uint)_encCircularBuffer.Size;
                if (bufSize <= 0)
                {
                    return;
                }
                var    chunklength = (int)Math.Min(bufSize, CHUNK_MAX_LEN_WITH_GARBAGE);
                byte[] chunkBytes  = _encCircularBuffer.Get(chunklength);

                byte[] garbage       = GetGarbage(chunklength, false);
                int    garbageLength = garbage.Length;
                Logging.Debug("garbage len: " + garbageLength);
                byte[] chunkWithGarbage = new byte[chunklength + garbageLength];
                PerfByteCopy(garbage, 0, chunkWithGarbage, 0, garbageLength);
                PerfByteCopy(chunkBytes, 0, chunkWithGarbage, garbageLength, chunklength);
                chunklength += garbageLength;

                int    encChunkLength;
                byte[] encChunkBytes = new byte[chunklength + tagLen * 2 + CHUNK_LEN_BYTES];
                ChunkEncrypt(chunkWithGarbage, chunklength, encChunkBytes, out encChunkLength);
                Debug.Assert(encChunkLength == chunklength + tagLen * 2 + CHUNK_LEN_BYTES);
                PerfByteCopy(encChunkBytes, 0, outbuf, outlength, encChunkLength);
                outlength += encChunkLength;
                Logging.Debug("chunks enc outlength " + outlength);
                // check if we have enough space for outbuf
                if (outlength + ChunkOverheadSize > TCPRelay.BufferSize)
                {
                    Logging.Debug("enc outbuf almost full, giving up");
                    return;
                }
                bufSize = (uint)_encCircularBuffer.Size;
                if (bufSize <= 0)
                {
                    Logging.Debug("No more data to encrypt, leaving");
                    return;
                }
            }
        }