Exemplo n.º 1
0
        public Exchange(Self localIdentity, byte csid, byte[] publicKey)
        {
            Local = localIdentity;

            cipherSet = localIdentity.CipherSets [csid];
            var ri = new CS1ARemoteInfo();

            ri.RemotePublicKey = publicKey;
            cipherSet.GenerateEphemeralKeys(ri);
            remoteInfo = ri;

            var idKey = localIdentity.CipherSets [csid].Keys.PublicKey;

            for (int i = 0; i < publicKey.Length; ++i)
            {
                if (publicKey [i] == idKey [i])
                {
                    continue;
                }
                if (publicKey [i] > idKey [i])
                {
                    Order = HashOrder.High;
                    At    = 1;
                    break;
                }
                else
                {
                    Order = HashOrder.Low;
                    At    = 2;
                    break;
                }
            }
        }
Exemplo n.º 2
0
		public void GenerateEphemeralKeys(ICipherSetRemoteInfo remoteInfo)
		{
			CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;
			ri.EphemeralKeys = ECKeyPair.Generate (SecNamedCurves.GetByName ("secp160r1"));
			var hashToken = Helpers.SHA256Hash (ri.EphemeralKeys.PublicKey.Take(16).ToArray());
			ri.Token = hashToken.Take (16).ToArray ();
		}
Exemplo n.º 3
0
        public Packet ChannelDecrypt(ICipherSetRemoteInfo channelInfo, Packet outer)
        {
            // We gotta have the primary components and something to decrypt
            if (outer.Body.Length < 25)
            {
                return(null);
            }

            var ci = (CS1ARemoteInfo)channelInfo;

            // Rip apart our packet
            byte[] token         = outer.Body.Take(16).ToArray();
            byte[] iv            = outer.Body.Skip(16).Take(4).ToArray();
            byte[] encryptedData = outer.Body.Skip(20).Take(outer.Body.Length - 24).ToArray();
            byte[] dataMac       = outer.Body.Skip(outer.Body.Length - 4).Take(4).ToArray();

            // Make sure we're on the right channel
            if (!token.SequenceEqual(ci.Token))
            {
                return(null);
            }

            // Validate us some hmac
            byte[] hmacKey = new byte[20];
            Buffer.BlockCopy(ci.DecryptionKey, 0, hmacKey, 0, 16);
            Buffer.BlockCopy(iv, 0, hmacKey, 16, 4);

            var hmac = new HMac(new Sha256Digest());

            hmac.Init(new KeyParameter(hmacKey));
            hmac.BlockUpdate(encryptedData, 0, encryptedData.Length);
            byte[] mac = new byte[hmac.GetMacSize()];
            hmac.DoFinal(mac, 0);
            var foldedMac = Helpers.Fold(mac, 3);

            if (!foldedMac.SequenceEqual(dataMac))
            {
                // Get out of here with your bad data
                return(null);
            }

            // Everything seems ok.  Get it decrypted
            byte[] aesIV = new byte[16];
            Buffer.BlockCopy(iv, 0, aesIV, 0, 4);
            Array.Clear(aesIV, 4, 12);

            var cipher     = new SicBlockCipher(new AesFastEngine());
            var parameters = new ParametersWithIV(new KeyParameter(ci.DecryptionKey), aesIV);

            cipher.Init(false, parameters);

            var decryptedData = new byte[encryptedData.Length];
            BufferedBlockCipher bufferCipher = new BufferedBlockCipher(cipher);
            var offset = bufferCipher.ProcessBytes(encryptedData, decryptedData, 0);

            bufferCipher.DoFinal(decryptedData, offset);

            // Build a packet and ship it off
            return(Packet.DecodePacket(decryptedData));
        }
Exemplo n.º 4
0
		public Exchange (Self localIdentity, byte csid, byte[] publicKey)
		{
			Local = localIdentity;

			cipherSet = localIdentity.CipherSets [csid];
			var ri = new CS1ARemoteInfo ();
			ri.RemotePublicKey = publicKey;
			cipherSet.GenerateEphemeralKeys (ri);
			remoteInfo = ri;

			var idKey = localIdentity.CipherSets [csid].Keys.PublicKey;
			for (int i = 0; i < publicKey.Length; ++i) {
				if (publicKey [i] == idKey [i]) {
					continue;
				}
				if (publicKey [i] > idKey [i]) {
					Order = HashOrder.High;
					At = 1;
					break;
				} else {
					Order = HashOrder.Low;
					At = 2;
					break;
				}
			}
		}
Exemplo n.º 5
0
        public void GenerateEphemeralKeys(ICipherSetRemoteInfo remoteInfo)
        {
            CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;

            ri.EphemeralKeys = ECKeyPair.Generate(SecNamedCurves.GetByName("secp160r1"));
            var hashToken = Helpers.SHA256Hash(ri.EphemeralKeys.PublicKey.Take(16).ToArray());

            ri.Token = hashToken.Take(16).ToArray();
        }
Exemplo n.º 6
0
		public Packet MessageEncrypt(ICipherSetRemoteInfo remoteInfo, Packet inner)
		{
			CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;

			var agreedValue = ECDHAgree (ri.RemotePublicKey, ri.EphemeralKeys.PrivateKey);

			// Hash the agreed key
			var hashedValue = Helpers.SHA256Hash (Helpers.ToByteArray(agreedValue, 20));

			// Fold to get the actual key for AES
			byte[] aesKey = Helpers.Fold (hashedValue);
			Random rnd = new Random ();

			// Setup and encrypt the actual data
			byte[] aesIV = new byte[16];
			rnd.NextBytes (aesIV);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (aesKey), aesIV);
			cipher.Init (true, parameters);

			var encryptedInner = new byte[inner.FullPacket.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (inner.FullPacket, encryptedInner, 0);
			bufferCipher.DoFinal (encryptedInner, offset);

			// Construct the packet minus the hmac
			Packet outPacket = new Packet ();
			outPacket.Body = new byte[29 + encryptedInner.Length];
			Buffer.BlockCopy (ri.EphemeralKeys.PublicKey, 0, outPacket.Body, 0, ri.EphemeralKeys.PublicKey.Length);
			Buffer.BlockCopy (aesIV, 0, outPacket.Body, 21, 4);
			Buffer.BlockCopy (encryptedInner, 0, outPacket.Body, 25, encryptedInner.Length);

			// ECDH for the hmac key using 
			var idAgreedValue = ECDHAgree (ri.RemotePublicKey, Key.PrivateKey);

			// Mash on the IV for the compound key
			byte[] macKey = new byte[24];
			byte[] idAgreedValueArray = Helpers.ToByteArray(idAgreedValue, 20);
			Buffer.BlockCopy(idAgreedValueArray, 0, macKey, 0, idAgreedValueArray.Length);
			Buffer.BlockCopy(aesIV, 0, macKey, idAgreedValueArray.Length, 4);

			// Actually hmac all the data now
			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (macKey, 0, 24));
			hmac.BlockUpdate(outPacket.Body, 0, 25 + encryptedInner.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);

			// Fold it up, shove it in and we're done
			var foldedMac = Helpers.Fold(mac, 3);
			Buffer.BlockCopy(foldedMac, 0, outPacket.Body, 25 + encryptedInner.Length, foldedMac.Length);

			return outPacket;
		}
Exemplo n.º 7
0
        public Packet ChannelEncrypt(ICipherSetRemoteInfo channelInfo, Packet inner)
        {
            var ci = (CS1ARemoteInfo)channelInfo;

            // TODO:  Validate we don't care about endianess of IV here

            // Setup and encrypt the actual data
            byte[] aesIV = new byte[16];
            Buffer.BlockCopy(BitConverter.GetBytes(ci.IV), 0, aesIV, 0, 4);
            Array.Clear(aesIV, 4, 12);

            var cipher     = new SicBlockCipher(new AesFastEngine());
            var parameters = new ParametersWithIV(new KeyParameter(ci.EncryptionKey), aesIV);

            cipher.Init(true, parameters);

            var encryptedInner = new byte[inner.FullPacket.Length];
            BufferedBlockCipher bufferCipher = new BufferedBlockCipher(cipher);
            var offset = bufferCipher.ProcessBytes(inner.FullPacket, encryptedInner, 0);

            bufferCipher.DoFinal(encryptedInner, offset);

            // Hmac the output
            byte[] hmacKey = new byte[20];
            Buffer.BlockCopy(ci.EncryptionKey, 0, hmacKey, 0, 16);
            Buffer.BlockCopy(BitConverter.GetBytes(ci.IV), 0, hmacKey, 16, 4);

            var hmac = new HMac(new Sha256Digest());

            hmac.Init(new KeyParameter(hmacKey));
            hmac.BlockUpdate(encryptedInner, 0, encryptedInner.Length);
            byte[] mac = new byte[hmac.GetMacSize()];
            hmac.DoFinal(mac, 0);
            var foldedMac = Helpers.Fold(mac, 3);

            // Create the outgoing packet
            Packet outPacket = new Packet();

            outPacket.Body = new byte[encryptedInner.Length + 24];
            Buffer.BlockCopy(ci.Token, 0, outPacket.Body, 0, 16);
            Buffer.BlockCopy(BitConverter.GetBytes(ci.IV), 0, outPacket.Body, 16, 4);
            Buffer.BlockCopy(encryptedInner, 0, outPacket.Body, 20, encryptedInner.Length);
            Buffer.BlockCopy(foldedMac, 0, outPacket.Body, outPacket.Body.Length - 4, 4);

            // Next IV next packet
            ++ci.IV;

            return(outPacket);
        }
Exemplo n.º 8
0
        public bool MessageVerify(ICipherSetRemoteInfo remoteInfo, Packet outer)
        {
            CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;

            byte[] ivData   = outer.Body.Skip(21).Take(4).ToArray();
            byte[] hmacData = outer.Body.Skip(outer.Body.Length - 4).Take(4).ToArray();

            // Check the hmac to validate the packet
            var agreedHMacKeyData = Helpers.ToByteArray(ECDHAgree(ri.RemotePublicKey, Key.PrivateKey), 20);

            byte[] hmacKey = new byte[24];
            if (agreedHMacKeyData.Length != 20)
            {
                // It's not a correct agreed value, expected 20 bytes
                return(false);
            }
            Buffer.BlockCopy(agreedHMacKeyData, 0, hmacKey, 0, 20);
            Buffer.BlockCopy(ivData, 0, hmacKey, 20, 4);

            var hmac = new HMac(new Sha256Digest());

            byte[] fullIv = new byte[16];
            Array.Clear(fullIv, 0, 16);
            Buffer.BlockCopy(ivData, 0, fullIv, 0, 4);
            hmac.Init(new KeyParameter(hmacKey, 0, 24));
            hmac.BlockUpdate(outer.Body, 0, outer.Body.Length - 4);
            byte[] mac = new byte[hmac.GetMacSize()];
            hmac.DoFinal(mac, 0);
            var macValue = Helpers.Fold(mac, 3);

            if (!macValue.SequenceEqual(hmacData))
            {
                // The hmacs did not match, blow up the world
                return(false);
            }

            return(true);
        }
Exemplo n.º 9
0
        public void Prepare(ICipherSetRemoteInfo info, Packet outer)
        {
            var ri = (CS1ARemoteInfo)info;

            ri.RemoteEphemeralKey = new byte[21];
            Buffer.BlockCopy(outer.Parent.Body, 0, ri.RemoteEphemeralKey, 0, 21);

            var secret    = Helpers.ToByteArray(ECDHAgree(ri.RemoteEphemeralKey, ri.EphemeralKeys.PrivateKey), 20);
            var shaBuffer = new byte[secret.Length + ri.RemoteEphemeralKey.Length + ri.EphemeralKeys.PublicKey.Length];

            Buffer.BlockCopy(secret, 0, shaBuffer, 0, secret.Length);
            Buffer.BlockCopy(ri.RemoteEphemeralKey, 0, shaBuffer, secret.Length, ri.RemoteEphemeralKey.Length);
            Buffer.BlockCopy(ri.EphemeralKeys.PublicKey, 0, shaBuffer, secret.Length + ri.RemoteEphemeralKey.Length, ri.EphemeralKeys.PublicKey.Length);
            ri.DecryptionKey = Helpers.FoldOnce(Helpers.SHA256Hash(shaBuffer));

            Buffer.BlockCopy(ri.EphemeralKeys.PublicKey, 0, shaBuffer, secret.Length, ri.EphemeralKeys.PublicKey.Length);
            Buffer.BlockCopy(ri.RemoteEphemeralKey, 0, shaBuffer, secret.Length + ri.EphemeralKeys.PublicKey.Length, ri.RemoteEphemeralKey.Length);
            ri.EncryptionKey = Helpers.FoldOnce(Helpers.SHA256Hash(shaBuffer));

            var rnd = new SecureRandom();

            ri.IV = (uint)rnd.NextInt();
        }
Exemplo n.º 10
0
		public void Prepare(ICipherSetRemoteInfo info, Packet outer)
		{
			var ri = (CS1ARemoteInfo)info;

			ri.RemoteEphemeralKey = new byte[21];
			Buffer.BlockCopy (outer.Parent.Body, 0, ri.RemoteEphemeralKey, 0, 21);

			var secret = Helpers.ToByteArray(ECDHAgree (ri.RemoteEphemeralKey, ri.EphemeralKeys.PrivateKey), 20);
			var shaBuffer = new byte[secret.Length + ri.RemoteEphemeralKey.Length + ri.EphemeralKeys.PublicKey.Length];

			Buffer.BlockCopy (secret, 0, shaBuffer, 0, secret.Length);
			Buffer.BlockCopy (ri.RemoteEphemeralKey, 0, shaBuffer, secret.Length, ri.RemoteEphemeralKey.Length);
			Buffer.BlockCopy (ri.EphemeralKeys.PublicKey, 0, shaBuffer, secret.Length + ri.RemoteEphemeralKey.Length, ri.EphemeralKeys.PublicKey.Length);
			ri.DecryptionKey = Helpers.FoldOnce (Helpers.SHA256Hash (shaBuffer));

			Buffer.BlockCopy (ri.EphemeralKeys.PublicKey, 0, shaBuffer, secret.Length, ri.EphemeralKeys.PublicKey.Length);
			Buffer.BlockCopy (ri.RemoteEphemeralKey, 0, shaBuffer, secret.Length + ri.EphemeralKeys.PublicKey.Length, ri.RemoteEphemeralKey.Length);
			ri.EncryptionKey = Helpers.FoldOnce (Helpers.SHA256Hash (shaBuffer));

			var rnd = new SecureRandom ();
			ri.IV = (uint)rnd.NextInt ();

		}
Exemplo n.º 11
0
		public Packet ChannelDecrypt(ICipherSetRemoteInfo channelInfo, Packet outer)
		{
			// We gotta have the primary components and something to decrypt
			if (outer.Body.Length < 25) {
				return null;
			}

			var ci = (CS1ARemoteInfo)channelInfo;

			// Rip apart our packet
			byte[] token = outer.Body.Take (16).ToArray ();
			byte[] iv = outer.Body.Skip (16).Take (4).ToArray ();
			byte[] encryptedData = outer.Body.Skip (20).Take (outer.Body.Length - 24).ToArray ();
			byte[] dataMac = outer.Body.Skip (outer.Body.Length - 4).Take (4).ToArray ();

			// Make sure we're on the right channel
			if (!token.SequenceEqual (ci.Token)) {
				return null;
			}

			// Validate us some hmac
			byte[] hmacKey = new byte[20];
			Buffer.BlockCopy (ci.DecryptionKey, 0, hmacKey, 0, 16);
			Buffer.BlockCopy (iv, 0, hmacKey, 16, 4);

			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (hmacKey));
			hmac.BlockUpdate(encryptedData, 0, encryptedData.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var foldedMac = Helpers.Fold (mac, 3);

			if (!foldedMac.SequenceEqual (dataMac)) {
				// Get out of here with your bad data
				return null;
			}

			// Everything seems ok.  Get it decrypted
			byte[] aesIV = new byte[16];
			Buffer.BlockCopy (iv, 0, aesIV, 0, 4);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (ci.DecryptionKey), aesIV);
			cipher.Init (false, parameters);

			var decryptedData = new byte[encryptedData.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (encryptedData, decryptedData, 0);
			bufferCipher.DoFinal (decryptedData, offset);

			// Build a packet and ship it off
			return Packet.DecodePacket (decryptedData);
		}
Exemplo n.º 12
0
		public Packet ChannelEncrypt(ICipherSetRemoteInfo channelInfo, Packet inner)
		{
			var ci = (CS1ARemoteInfo)channelInfo;

			// TODO:  Validate we don't care about endianess of IV here

			// Setup and encrypt the actual data
			byte[] aesIV = new byte[16];
			Buffer.BlockCopy (BitConverter.GetBytes(ci.IV), 0, aesIV, 0, 4);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (ci.EncryptionKey), aesIV);
			cipher.Init (true, parameters);

			var encryptedInner = new byte[inner.FullPacket.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (inner.FullPacket, encryptedInner, 0);
			bufferCipher.DoFinal (encryptedInner, offset);

			// Hmac the output
			byte[] hmacKey = new byte[20];
			Buffer.BlockCopy (ci.EncryptionKey, 0, hmacKey, 0, 16);
			Buffer.BlockCopy (BitConverter.GetBytes(ci.IV), 0, hmacKey, 16, 4);

			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (hmacKey));
			hmac.BlockUpdate(encryptedInner, 0, encryptedInner.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var foldedMac = Helpers.Fold (mac, 3);

			// Create the outgoing packet
			Packet outPacket = new Packet();
			outPacket.Body = new byte[encryptedInner.Length + 24];
			Buffer.BlockCopy(ci.Token, 0, outPacket.Body, 0, 16);
			Buffer.BlockCopy(BitConverter.GetBytes(ci.IV), 0, outPacket.Body, 16, 4);
			Buffer.BlockCopy(encryptedInner, 0, outPacket.Body, 20, encryptedInner.Length);
			Buffer.BlockCopy(foldedMac, 0, outPacket.Body, outPacket.Body.Length - 4, 4);

			// Next IV next packet
			++ci.IV;

			return outPacket;
		}
Exemplo n.º 13
0
		public bool MessageVerify (ICipherSetRemoteInfo remoteInfo, Packet outer)
		{
			CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;
			byte[] ivData = outer.Body.Skip(21).Take(4).ToArray();
			byte[] hmacData = outer.Body.Skip(outer.Body.Length - 4).Take(4).ToArray();

			// Check the hmac to validate the packet
			var agreedHMacKeyData = Helpers.ToByteArray (ECDHAgree (ri.RemotePublicKey, Key.PrivateKey), 20);
			byte[] hmacKey = new byte[24];
			if (agreedHMacKeyData.Length != 20) {
				// It's not a correct agreed value, expected 20 bytes
				return false;
			}
			Buffer.BlockCopy (agreedHMacKeyData, 0, hmacKey, 0, 20);
			Buffer.BlockCopy (ivData, 0, hmacKey, 20, 4);

			var hmac = new HMac (new Sha256Digest ());
			byte[] fullIv = new byte[16];
			Array.Clear (fullIv, 0, 16);
			Buffer.BlockCopy (ivData, 0, fullIv, 0, 4);
			hmac.Init(new KeyParameter (hmacKey, 0, 24));
			hmac.BlockUpdate(outer.Body, 0, outer.Body.Length - 4);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var macValue = Helpers.Fold (mac, 3);

			if (!macValue.SequenceEqual (hmacData)) {
				// The hmacs did not match, blow up the world
				return false;
			}

			return true;
		}
Exemplo n.º 14
0
        public Packet MessageEncrypt(ICipherSetRemoteInfo remoteInfo, Packet inner)
        {
            CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;

            var agreedValue = ECDHAgree(ri.RemotePublicKey, ri.EphemeralKeys.PrivateKey);

            // Hash the agreed key
            var hashedValue = Helpers.SHA256Hash(Helpers.ToByteArray(agreedValue, 20));

            // Fold to get the actual key for AES
            byte[] aesKey = Helpers.Fold(hashedValue);
            Random rnd    = new Random();

            // Setup and encrypt the actual data
            byte[] aesIV = new byte[16];
            rnd.NextBytes(aesIV);
            Array.Clear(aesIV, 4, 12);

            var cipher     = new SicBlockCipher(new AesFastEngine());
            var parameters = new ParametersWithIV(new KeyParameter(aesKey), aesIV);

            cipher.Init(true, parameters);

            var encryptedInner = new byte[inner.FullPacket.Length];
            BufferedBlockCipher bufferCipher = new BufferedBlockCipher(cipher);
            var offset = bufferCipher.ProcessBytes(inner.FullPacket, encryptedInner, 0);

            bufferCipher.DoFinal(encryptedInner, offset);

            // Construct the packet minus the hmac
            Packet outPacket = new Packet();

            outPacket.Body = new byte[29 + encryptedInner.Length];
            Buffer.BlockCopy(ri.EphemeralKeys.PublicKey, 0, outPacket.Body, 0, ri.EphemeralKeys.PublicKey.Length);
            Buffer.BlockCopy(aesIV, 0, outPacket.Body, 21, 4);
            Buffer.BlockCopy(encryptedInner, 0, outPacket.Body, 25, encryptedInner.Length);

            // ECDH for the hmac key using
            var idAgreedValue = ECDHAgree(ri.RemotePublicKey, Key.PrivateKey);

            // Mash on the IV for the compound key
            byte[] macKey             = new byte[24];
            byte[] idAgreedValueArray = Helpers.ToByteArray(idAgreedValue, 20);
            Buffer.BlockCopy(idAgreedValueArray, 0, macKey, 0, idAgreedValueArray.Length);
            Buffer.BlockCopy(aesIV, 0, macKey, idAgreedValueArray.Length, 4);

            // Actually hmac all the data now
            var hmac = new HMac(new Sha256Digest());

            hmac.Init(new KeyParameter(macKey, 0, 24));
            hmac.BlockUpdate(outPacket.Body, 0, 25 + encryptedInner.Length);
            byte[] mac = new byte[hmac.GetMacSize()];
            hmac.DoFinal(mac, 0);

            // Fold it up, shove it in and we're done
            var foldedMac = Helpers.Fold(mac, 3);

            Buffer.BlockCopy(foldedMac, 0, outPacket.Body, 25 + encryptedInner.Length, foldedMac.Length);

            return(outPacket);
        }