示例#1
0
        public virtual void Init(
            bool forEncryption,
            ICipherParameters parameters)
        {
            _forEncryption = forEncryption;

            KeyParameter keyParam;

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

                _nonce = param.GetNonce();
                _initialAssociatedText = param.GetAssociatedText();

                keyParam = param.Key;
            }
            else if (parameters is ParametersWithIV)
            {
                ParametersWithIV param = (ParametersWithIV)parameters;

                _nonce = param.GetIV();
                _initialAssociatedText = null;
                keyParam = (KeyParameter)param.Parameters;
            }
            else
            {
                throw new ArgumentException("invalid parameters passed to ChaCha20Poly1305");
            }

            if (_nonce == null || _nonce.Length < 1)
            {
                throw new ArgumentException("IV must be at least 1 byte");
            }

            //  Geneate the key
            ChaCha7539Engine tmpCypher = new ChaCha7539Engine();

            byte[]           zero    = new byte[32];
            byte[]           polyKey = new byte[32];
            ParametersWithIV tmpKey  = new ParametersWithIV(keyParam, _nonce);

            tmpCypher.Init(true, tmpKey);
            tmpCypher.ProcessBytes(zero, 0, zero.Length, polyKey, 0);

            _poly = new Poly1305();

            KeyParameter tmpKey2 = new KeyParameter(polyKey);

            _poly.Init(tmpKey2);

            _chacha20 = new ChaChaX();
            _chacha20.Init(forEncryption, tmpKey);

            InitCipher();
        }
示例#2
0
        /// <exception cref="IOException"></exception>
        public Chacha20Poly1305(TlsContext context)
        {
            if (!TlsUtilities.IsTlsV12(context))
                throw new TlsFatalAlert(AlertDescription.internal_error);

            this.context = context;

            int cipherKeySize = 32;
            // TODO SecurityParameters.fixed_iv_length
            int fixed_iv_length = 12;
            // TODO SecurityParameters.record_iv_length = 0

            int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length);

            byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size);

            int offset = 0;

            KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;
            KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;
            byte[] client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length);
            offset += fixed_iv_length;
            byte[] server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length);
            offset += fixed_iv_length;

            if (offset != key_block_size)
                throw new TlsFatalAlert(AlertDescription.internal_error);

            this.encryptCipher = new ChaCha7539Engine();
            this.decryptCipher = new ChaCha7539Engine();

            KeyParameter encryptKey, decryptKey;
            if (context.IsServer)
            {
                encryptKey = server_write_key;
                decryptKey = client_write_key;
                this.encryptIV = server_write_IV;
                this.decryptIV = client_write_IV;
            }
            else
            {
                encryptKey = client_write_key;
                decryptKey = server_write_key;
                this.encryptIV = client_write_IV;
                this.decryptIV = server_write_IV;
            }

            this.encryptCipher.Init(true, new ParametersWithIV(encryptKey, encryptIV));
            this.decryptCipher.Init(false, new ParametersWithIV(decryptKey, decryptIV));
        }
示例#3
0
        public byte[] Decrypt(byte[] cipher, byte[] key, byte[] iv, byte[] aad = null, byte[] associated = null)
        {
            if (key.Length * 8 != this.KeySize)
            {
                throw new InvalidOperationException($"the given key has invalid size {key.Length * 8}, expect {this.KeySize}");
            }
            if (iv.Length != 12)
            {
                throw new InvalidOperationException($"chacha20 requires 96 bits IV, got {iv.Length * 8}");
            }
            if (cipher.Length <= 16)
            {
                throw new ArgumentException($"incorrect argument [cipher] size");
            }
            // split cipher and mac
            var cipherText = cipher.Take(cipher.Length - 16).ToArray();
            var macText    = cipher.Skip(cipher.Length - 16).ToArray();

            var engine = new Engines.ChaCha7539Engine();

            engine.Init(false, new Parameters.ParametersWithIV(new Parameters.KeyParameter(key), iv));
            // calculate mac key
            var mackeyBlock = new byte[64];

            engine.ProcessBytes(mackeyBlock, 0, mackeyBlock.Length, mackeyBlock, 0);
            var mackey = mackeyBlock.Take(32).ToArray();
            // calculate mac
            var poly = new Macs.Poly1305();

            poly.Init(new Parameters.KeyParameter(mackey));
            PolyUpdateMacText(poly, aad);
            PolyUpdateMacText(poly, cipherText);
            PolyUpdateMacLength(poly, aad.Length);
            PolyUpdateMacLength(poly, cipherText.Length);
            var myMac = PolyDoFinal(poly);

            if (!Utils.BytesEqual(myMac, macText))
            {
                throw new ArgumentException("bad record mac");
            }
            // decrypt
            var plain = new byte[cipherText.Length];

            engine.ProcessBytes(cipherText, 0, cipherText.Length, plain, 0);
            return(plain);
        }
示例#4
0
        public byte[] Encrypt(byte[] plain, byte[] key, byte[] iv, byte[] aad = null, byte[] associated = null)
        {
            if (key.Length * 8 != this.KeySize)
            {
                throw new InvalidOperationException($"the given key has invalid size {key.Length * 8}, expect {this.KeySize}");
            }
            if (iv.Length != 12)
            {
                throw new InvalidOperationException($"chacha20 requires 96 bits IV, got {iv.Length * 8}");
            }

            var engine = new Engines.ChaCha7539Engine();

            engine.Init(true, new Parameters.ParametersWithIV(new Parameters.KeyParameter(key), iv));
            // calculate mac key
            var mackeyBlock = new byte[64];

            engine.ProcessBytes(mackeyBlock, 0, mackeyBlock.Length, mackeyBlock, 0);
            var mackey = mackeyBlock.Take(32).ToArray();
            // encrypt
            var cipher = new byte[plain.Length];

            engine.ProcessBytes(plain, 0, plain.Length, cipher, 0);
            // calculate mac
            var poly = new Macs.Poly1305();

            poly.Init(new Parameters.KeyParameter(mackey));
            PolyUpdateMacText(poly, aad);
            PolyUpdateMacText(poly, cipher);
            PolyUpdateMacLength(poly, aad.Length);
            PolyUpdateMacLength(poly, cipher.Length);
            var myMac       = PolyDoFinal(poly);
            var cipherBlock = new byte[cipher.Length + myMac.Length];

            Buffer.BlockCopy(cipher, 0, cipherBlock, 0, cipher.Length);
            Buffer.BlockCopy(myMac, 0, cipherBlock, cipher.Length, myMac.Length);
            return(cipherBlock);
        }