Exemplo n.º 1
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.º 2
0
 private void InitMac()
 {
     byte[] firstBlock = new byte[64];
     try
     {
         mChacha20.ProcessBytes(firstBlock, 0, 64, firstBlock, 0);
         mPoly1305.Init(new KeyParameter(firstBlock, 0, 32));
     }
     finally
     {
         Array.Clear(firstBlock, 0, 64);
     }
 }
Exemplo n.º 3
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len)
        {
            KeyParameter macKey = InitRecord(encryptCipher, true, seqNo, encryptIV);

            byte[] output = new byte[len + 16];
            encryptCipher.ProcessBytes(plaintext, offset, len, output, 0);

            byte[] additionalData = GetAdditionalData(seqNo, type, len);
            byte[] mac            = CalculateRecordMac(macKey, additionalData, output, 0, len);
            Array.Copy(mac, 0, output, len, mac.Length);

            return(output);
        }
Exemplo n.º 4
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);
            }
        }
Exemplo n.º 5
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);
        }
        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.º 7
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);
        }
        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);
        }
Exemplo n.º 9
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.º 10
0
        /// <exception cref="IOException"></exception>
        public /*virtual */ BufferSegment EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len)
        {
            KeyParameter macKey = InitRecord(encryptCipher, true, seqNo, encryptIV);

            byte[] output = BufferPool.Get(len + 16, true);
            encryptCipher.ProcessBytes(plaintext, offset, len, output, 0);

            BufferSegment additionalData = GetAdditionalData(seqNo, type, len);
            BufferSegment mac            = CalculateRecordMac(macKey, additionalData, output, 0, len);

            Array.Copy(mac.Data, mac.Offset, output, len, mac.Count);

            BufferPool.Release(additionalData);
            BufferPool.Release(mac);

            return(new BufferSegment(output, 0, len + 16));
        }
        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);
        }