/// <exception cref="IOException"></exception>
        public Chacha20Poly1305(TlsContext context)
        {
            if (!TlsUtilities.IsTlsV12(context))
                throw new TlsFatalAlert(AlertDescription.internal_error);

            this.context = context;

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

            KeyParameter client_write_key = new KeyParameter(key_block, 0, 32);
            KeyParameter server_write_key = new KeyParameter(key_block, 32, 32);

            this.encryptCipher = new ChaChaEngine(20);
            this.decryptCipher = new ChaChaEngine(20);

            KeyParameter encryptKey, decryptKey;
            if (context.IsServer)
            {
                encryptKey = server_write_key;
                decryptKey = client_write_key;
            }
            else
            {
                encryptKey = client_write_key;
                decryptKey = server_write_key;
            }

            byte[] dummyNonce = new byte[8];

            this.encryptCipher.Init(true, new ParametersWithIV(encryptKey, dummyNonce));
            this.decryptCipher.Init(false, new ParametersWithIV(decryptKey, dummyNonce));
        }
Beispiel #2
0
 protected override void GenerateKeyStream(byte[] output)
 {
     ChaChaEngine.ChachaCore(rounds, engineState, x);
     Pack.UInt32_To_LE(x, output, 0);
 }
Beispiel #3
0
		public byte[] Cloak()
		{
			Encode ();

			byte[] outData = new byte[FullPacket.Length + 8];

			// Get our nonce
			Random rnd = new Random ();
			byte[] nonce = new byte[8];
			rnd.NextBytes (nonce);
			// We can't have a leading 0 byte
			if (nonce [0] == 0) {
				nonce [0] = 1;
			}

			var parms = new ParametersWithIV(new KeyParameter(cloakKey), nonce);
			var chacha = new ChaChaEngine(20);
			chacha.Init(true, parms);
			chacha.ProcessBytes (FullPacket, 0, FullPacket.Length, outData, 8);
			Buffer.BlockCopy (nonce, 0, outData, 0, 8);

			return outData;
		}
Beispiel #4
0
		/// <summary>
		/// Decloak the given buffer and return the valid Packet from it
		/// </summary>
		/// <param name="buffer">A cloaked packet buffer.</param>
		static public Packet Decloak(byte[] buffer)
		{
			if (buffer.Length < 8 || buffer [0] == 0) {
				return Packet.DecodePacket (buffer);
			}

			byte[] nonce = buffer.Take (8).ToArray ();
			var parms = new ParametersWithIV(new KeyParameter(cloakKey), nonce);

			var chacha = new ChaChaEngine(20);
			chacha.Init(false, parms);
			byte[] outBuff = new byte[buffer.Length - 8];
			chacha.ProcessBytes(buffer, 8, buffer.Length - 8, outBuff, 0);

			return Decloak (outBuff);
		}
        protected virtual KeyParameter InitRecordMac(ChaChaEngine cipher, bool forEncryption, long seqNo)
        {
            byte[] nonce = new byte[8];
            TlsUtilities.WriteUint64(seqNo, nonce, 0);

            cipher.Init(forEncryption, new ParametersWithIV(null, nonce));

            byte[] firstBlock = new byte[64];
            cipher.ProcessBytes(firstBlock, 0, firstBlock.Length, firstBlock, 0);

            // NOTE: The BC implementation puts 'r' after 'k'
            Array.Copy(firstBlock, 0, firstBlock, 32, 16);
            KeyParameter macKey = new KeyParameter(firstBlock, 16, 32);
            Poly1305KeyGenerator.Clamp(macKey.GetKey());
            return macKey;
        }
Beispiel #6
0
        private void reinitBug()
        {
            KeyParameter key = new KeyParameter(Hex.Decode("80000000000000000000000000000000"));
            ParametersWithIV parameters = new ParametersWithIV(key, Hex.Decode("0000000000000000"));

            IStreamCipher chacha = new ChaChaEngine();

            chacha.Init(true, parameters);

            try
            {
                chacha.Init(true, key);
                Fail("ChaCha should throw exception if no IV in Init");
            }
            catch (ArgumentException)
            {
            }
        }
Beispiel #7
0
        private void chachaTest2(
            ICipherParameters	parameters,
            string				v0,
            string				v65472,
            string				v65536)
        {
            IStreamCipher salsa = new ChaChaEngine();
            byte[]       buf = new byte[64];

            salsa.Init(true, parameters);

            for (int i = 0; i != 1025; i++)
            {
                salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
                switch (i)
                {
                case 0:
                    if (!AreEqual(buf, Hex.Decode(v0)))
                    {
                        mismatch("v0", v0, buf);
                    }
                    break;
                case 1023:
                    if (!AreEqual(buf, Hex.Decode(v65472)))
                    {
                        mismatch("v65472", v65472, buf);
                    }
                    break;
                case 1024:
                    if (!AreEqual(buf, Hex.Decode(v65536)))
                    {
                        mismatch("v65536", v65536, buf);
                    }
                    break;
                default:
                    // ignore
                    break;
                }
            }
        }
Beispiel #8
0
        private void chachaTest1(
            int rounds,
            ICipherParameters	parameters,
            string				v0,
            string				v192,
            string				v256,
            string				v448)
        {
            IStreamCipher salsa = new ChaChaEngine(rounds);
            byte[]       buf = new byte[64];

            salsa.Init(true, parameters);

            for (int i = 0; i != 7; i++)
            {
                salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
                switch (i)
                {
                case 0:
                    if (!AreEqual(buf, Hex.Decode(v0)))
                    {
                        mismatch("v0/" + rounds, v0, buf);
                    }
                    break;
                case 3:
                    if (!AreEqual(buf, Hex.Decode(v192)))
                    {
                        mismatch("v192/" + rounds, v192, buf);
                    }
                    break;
                case 4:
                    if (!AreEqual(buf, Hex.Decode(v256)))
                    {
                        mismatch("v256/" + rounds, v256, buf);
                    }
                    break;
                default:
                    // ignore
                    break;
                }
            }

            for (int i = 0; i != 64; i++)
            {
                buf[i] = salsa.ReturnByte(zeroes[i]);
            }

            if (!AreEqual(buf, Hex.Decode(v448)))
            {
                mismatch("v448", v448, buf);
            }       
        }