Exemplo n.º 1
0
        public static int Encrypt(byte[] plaintext, int offset, int len, byte[] additionalData, byte[] nonce, byte[] key, byte[] outBuffer)
        {
            lock (mutex) {
                if (cipher == null)
                {
                    cipher = new ChaCha7539Engine();
                }
                else
                {
                    cipher.Reset();
                }

                if (_encryptKey == null)
                {
                    _encryptKey = new KeyParameter(key);
                }
                else
                {
                    _encryptKey.Reset();
                    _encryptKey.SetKey(key);
                }

                if (_temp_Params == null)
                {
                    _temp_Params = new ParametersWithIV(_encryptKey, nonce);
                }
                else
                {
                    _temp_Params.Reset();
                    _temp_Params.Set(_encryptKey, nonce);
                }

                cipher.Init(true, _temp_Params);

                byte[]       firstBlock = BufferPool.GetBuffer(64);
                KeyParameter macKey     = GenerateRecordMacKey(cipher, firstBlock);

                cipher.ProcessBytes(plaintext, offset, len, outBuffer, 0);

                byte[] mac     = BufferPool.GetBuffer(16);
                int    macsize = CalculateRecordMac(macKey, additionalData, outBuffer, 0, len, mac);
                Array.Copy(mac, 0, outBuffer, len, macsize);

                BufferPool.ReturnBuffer(mac);
                BufferPool.ReturnBuffer(firstBlock);

                return(len + 16);
            }
        }
        public static int Decrypt(byte[] ciphertext, int offset, int len, byte[] additionalData, byte[] nonce, byte[] key, byte[] outBuffer)
        {
            var cipher = new ChaCha7539Engine();

            var decryptKey = new KeyParameter(key);

            cipher.Init(false, new ParametersWithIV(decryptKey, nonce));

            byte[]       firstBlock = BufferPool.GetBuffer(64);
            KeyParameter macKey     = GenerateRecordMacKey(cipher, firstBlock);

            int plaintextLength = len - 16;

            byte[] calculatedMac = BufferPool.GetBuffer(16);
            CalculateRecordMac(macKey, additionalData, ciphertext, offset, plaintextLength, calculatedMac);

            byte[] receivedMac = BufferPool.GetBuffer(16);
            Array.Copy(ciphertext, offset + plaintextLength, receivedMac, 0, receivedMac.Length);

            if (!Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac))
            {
                BufferPool.ReturnBuffer(calculatedMac);
                BufferPool.ReturnBuffer(receivedMac);
                BufferPool.ReturnBuffer(firstBlock);

                throw new TlsFatalAlert(AlertDescription.bad_record_mac);
            }

            BufferPool.ReturnBuffer(calculatedMac);
            BufferPool.ReturnBuffer(receivedMac);
            BufferPool.ReturnBuffer(firstBlock);

            cipher.ProcessBytes(ciphertext, offset, plaintextLength, outBuffer, 0);
            return(plaintextLength);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Encrypt data with ChaCha20 RFC 7539
        /// </summary>
        /// <param name="input">Input stream to encrypt</param>
        /// <param name="output">Output stream</param>
        /// <param name="key">Key</param>
        /// <param name="nonce">Nonce</param>
        /// <param name="notifyProgression">Notify progression method</param>
        /// <param name="bufferSize">Buffer size</param>
        public static void Encrypt(Stream input, Stream output, byte[] key, byte[] nonce, Action <int> notifyProgression = null, int bufferSize = 4096)
        {
            ChaCha7539Engine engine     = new ChaCha7539Engine();
            ParametersWithIV parameters = new ParametersWithIV(new KeyParameter(key, 0, key.Length), nonce, 0, nonce.Length);

            engine.Init(true, parameters);

            int bytesRead;

            byte[] buffer = new byte[bufferSize];
            byte[] enc    = new byte[bufferSize];
            do
            {
                bytesRead = input.Read(buffer, 0, bufferSize);
                if (bytesRead > 0)
                {
                    engine.ProcessBytes(buffer, 0, bytesRead, enc, 0);
                    output.Write(enc, 0, bytesRead);

                    if (notifyProgression != null)
                    {
                        notifyProgression(bytesRead);
                    }
                }
            } while (bytesRead == bufferSize);
        }
Exemplo n.º 4
0
        static bool crypto_aead_chacha20poly1305_ietf_decrypt_detached(Memory <byte> m, ReadOnlyMemory <byte> c, ReadOnlyMemory <byte> mac, ReadOnlyMemory <byte> ad, ReadOnlyMemory <byte> npub, ReadOnlyMemory <byte> k)
        {
            var kk = k._AsSegment();
            var nn = npub._AsSegment();
            var cc = c._AsSegment();
            var aa = ad._AsSegment();
            var mm = m._AsSegment();

            byte[] block0 = new byte[64];

            ChaCha7539Engine ctx = new ChaCha7539Engine();

            ctx.Init(true, new ParametersWithIV(new KeyParameter(kk.Array, kk.Offset, kk.Count), nn.Array, nn.Offset, nn.Count));
            ctx.ProcessBytes(block0, 0, block0.Length, block0, 0);

            Poly1305 state = new Poly1305();

            state.Init(new KeyParameter(block0, 0, AeadChaCha20Poly1305KeySize));

            state.BlockUpdate(aa.Array, aa.Offset, aa.Count);
            if ((aa.Count % 16) != 0)
            {
                state.BlockUpdate(zero15, 0, 16 - (aa.Count % 16));
            }

            state.BlockUpdate(cc.Array, cc.Offset, cc.Count);
            if ((cc.Count % 16) != 0)
            {
                state.BlockUpdate(zero15, 0, 16 - (cc.Count % 16));
            }

            byte[] slen = BitConverter.GetBytes((ulong)aa.Count);
            if (Env.IsBigEndian)
            {
                Array.Reverse(slen);
            }
            state.BlockUpdate(slen, 0, slen.Length);

            byte[] mlen = BitConverter.GetBytes((ulong)cc.Count);
            if (Env.IsBigEndian)
            {
                Array.Reverse(mlen);
            }
            state.BlockUpdate(mlen, 0, mlen.Length);

            byte[] computed_mac = new byte[AeadChaCha20Poly1305MacSize];
            state.DoFinal(computed_mac, 0);

            if (computed_mac.AsSpan().SequenceEqual(mac.Span) == false)
            {
                return(false);
            }

            ctx.ProcessBytes(cc.Array, cc.Offset, cc.Count, mm.Array, mm.Offset);

            return(true);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Decrypt data with ChaCha20 RFC 7539
        /// </summary>
        /// <param name="data">Data to decrypt</param>
        /// <param name="key">Key</param>
        /// <param name="nonce">Nonce</param>
        /// <returns>Decrypted data</returns>
        public static byte[] Decrypt(byte[] data, byte[] key, byte[] nonce)
        {
            byte[] dec = new byte[data.Length];

            ChaCha7539Engine engine     = new ChaCha7539Engine();
            ParametersWithIV parameters = new ParametersWithIV(new KeyParameter(key, 0, key.Length), nonce, 0, nonce.Length);

            engine.Init(false, parameters);
            engine.ProcessBytes(data, 0, data.Length, dec, 0);

            return(dec);
        }
Exemplo n.º 6
0
        public static byte[] ChaCha20Encrypt(byte[] plainText, byte[] key, byte[] nonce, bool skipFirst64Byte = false)
        {
            var engine = new ChaCha7539Engine();

            engine.Init(true, new ParametersWithIV(new KeyParameter(key), nonce));
            var cipherText = new byte[plainText.Length];

            if (skipFirst64Byte)
            {
                engine.ProcessBytes(new byte[64], 0, 64, new byte[64], 0);
            }

            engine.ProcessBytes(plainText, 0, plainText.Length, cipherText, 0);
            return(cipherText);
        }
        private byte[] EncryptOrDecrypt(bool isEncrypt, byte[] input, byte[] key, byte[] nonce, bool skip1Block)
        {
            var eng      = new ChaCha7539Engine();
            var keyParam = new ParametersWithIV(new KeyParameter(key), nonce);

            eng.Init(isEncrypt, keyParam);
            var output = new byte[input.Length];

            if (skip1Block)
            {
                var dummy = new byte[64];
                eng.ProcessBytes(new byte[64], 0, 64, dummy, 0);
            }

            eng.ProcessBytes(input, 0, input.Length, output, 0);
            return(output);
        }
        public static int Encrypt(byte[] plaintext, int offset, int len, byte[] additionalData, byte[] nonce, byte[] key, byte[] outBuffer)
        {
            var cipher = new ChaCha7539Engine();

            var encryptKey = new KeyParameter(key);

            cipher.Init(true, new ParametersWithIV(encryptKey, nonce));

            byte[]       firstBlock = BufferPool.GetBuffer(64);
            KeyParameter macKey     = GenerateRecordMacKey(cipher, firstBlock);

            cipher.ProcessBytes(plaintext, offset, len, outBuffer, 0);

            byte[] mac     = BufferPool.GetBuffer(16);
            int    macsize = CalculateRecordMac(macKey, additionalData, outBuffer, 0, len, mac);

            Array.Copy(mac, 0, outBuffer, len, macsize);

            BufferPool.ReturnBuffer(mac);
            BufferPool.ReturnBuffer(firstBlock);

            return(len + 16);
        }
Exemplo n.º 9
0
        public virtual void Init(bool forEncryption, ICipherParameters parameters)
        {
            KeyParameter initKeyParam;

            byte[]            initNonce;
            ICipherParameters chacha20Params;

            if (parameters is AeadParameters)
            {
                AeadParameters aeadParams = (AeadParameters)parameters;

                int macSizeBits = aeadParams.MacSize;
                if ((MacSize * 8) != macSizeBits)
                {
                    throw new ArgumentException("Invalid value for MAC size: " + macSizeBits);
                }

                initKeyParam   = aeadParams.Key;
                initNonce      = aeadParams.GetNonce();
                chacha20Params = new ParametersWithIV(initKeyParam, initNonce);

                this.mInitialAad = aeadParams.GetAssociatedText();
            }
            else if (parameters is ParametersWithIV)
            {
                ParametersWithIV ivParams = (ParametersWithIV)parameters;

                initKeyParam   = (KeyParameter)ivParams.Parameters;
                initNonce      = ivParams.GetIV();
                chacha20Params = ivParams;

                this.mInitialAad = null;
            }
            else
            {
                throw new ArgumentException("invalid parameters passed to ChaCha20Poly1305", "parameters");
            }

            // Validate key
            if (null == initKeyParam)
            {
                if (State.Uninitialized == mState)
                {
                    throw new ArgumentException("Key must be specified in initial init");
                }
            }
            else
            {
                if (KeySize != initKeyParam.GetKey().Length)
                {
                    throw new ArgumentException("Key must be 256 bits");
                }
            }

            // Validate nonce
            if (null == initNonce || NonceSize != initNonce.Length)
            {
                throw new ArgumentException("Nonce must be 96 bits");
            }

            // Check for encryption with reused nonce
            if (State.Uninitialized != mState && forEncryption && Arrays.AreEqual(mNonce, initNonce))
            {
                if (null == initKeyParam || Arrays.AreEqual(mKey, initKeyParam.GetKey()))
                {
                    throw new ArgumentException("cannot reuse nonce for ChaCha20Poly1305 encryption");
                }
            }

            if (null != initKeyParam)
            {
                Array.Copy(initKeyParam.GetKey(), 0, mKey, 0, KeySize);
            }

            Array.Copy(initNonce, 0, mNonce, 0, NonceSize);

            mChacha20.Init(true, chacha20Params);

            this.mState = forEncryption ? State.EncInit : State.DecInit;

            Reset(true, false);
        }