Beispiel #1
0
 public void RotateSendKey()
 {
     (byte[] newChainingKey, byte[] newSendKey) = HmacSha256.ComputeHashes(ChainingKey, SendEncryptionKey);
     ChainingKey       = newChainingKey;
     SendEncryptionKey = newSendKey;
     SendNonce.Reset();
 }
Beispiel #2
0
 public void RotateReceiveKey()
 {
     (byte[] newChainingKey, byte[] newReceiveKey) = HmacSha256.ComputeHashes(ChainingKey, ReceiveDecryptionKey);
     ChainingKey          = newChainingKey;
     ReceiveDecryptionKey = newReceiveKey;
     ReceiveNonce.Reset();
 }
Beispiel #3
0
        public void GenerateHashesTest()
        {
            String salt = "2640f52eebcd9e882958951c794250eedb28002c05d7dc2ea0f195406042caf1";
            String data = "1e2fb3c8fe8fb9f262f649f64d26ecf0f2c0a805a767cf02dc2d77a6ef1fdcc3";

            (byte[] output1, byte[] output2) = HmacSha256.ComputeHashes(salt.HexToByteArray(), data.HexToByteArray());

            String output1Expected = "b61ec1191326fa240decc9564369dbb3ae2b34341d1e11ad64ed89f89180582f";
            String output2Expected = "e68f69b7f096d7917245f5e5cf8ae1595febe4d4644333c99f9c4a1282031c9f";

            Assert.Equal(output1Expected, output1.ToHex());
            Assert.Equal(output2Expected, output2.ToHex());
        }
Beispiel #4
0
        public byte[] ApplyActOne(ECKeyPair ephemeralKeyPair = null)
        {
            if (_state.HandshakeState != HandshakeState.Initialized)
            {
                throw new InvalidOperationException($"Invalid handshake state {_state.HandshakeState}. Must be Initialized");
            }

            _state.EphemeralKeyPair = ephemeralKeyPair ?? Secp256K1.GenerateKeyPair();
            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(_state.EphemeralKeyPair.PublicKeyCompressed));
            byte[] ss            = ECDH.ComputeHashedPoint(_state.RemoteAddress.PublicKey.PublicKeyParameters, _state.EphemeralKeyPair.PrivateKey);
            (byte[] chainingKey, byte[] tempK1) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);
            _state.ChainingKey = chainingKey;
            (_, byte[] tag)    = ChaCha20Poly1305.EncryptWithAdditionalData(tempK1, _state.SendNonce.GetBytes(), handshakeHash, new byte[0]);
            handshakeHash      = SHA256.ComputeHash(handshakeHash.ConcatToNewArray(tag));

            _state.HandshakeHash  = handshakeHash;
            _state.HandshakeState = HandshakeState.Act1;
            return(ByteExtensions.Combine(new byte[] { 0 }, _state.EphemeralKeyPair.PublicKeyCompressed, tag));
        }
Beispiel #5
0
        public byte[] ApplyActTwo(ECKeyPair initiatorEphemeralKey, ECKeyPair localEphemeralKey = null)
        {
            if (_state.HandshakeState != HandshakeState.Act1)
            {
                throw new InvalidOperationException($"Invalid Handshake state {_state.HandshakeState}. Must be Act1");
            }

            _state.EphemeralKeyPair = localEphemeralKey ?? Secp256K1.GenerateKeyPair();
            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(_state.EphemeralKeyPair.PublicKeyCompressed));
            byte[] ss            = ECDH.ComputeHashedPoint(initiatorEphemeralKey.PublicKeyParameters, _state.EphemeralKeyPair.PrivateKey);
            (byte[] chainingKey, byte[] tempK2) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);
            (_, byte[] tag1) = ChaCha20Poly1305.EncryptWithAdditionalData(tempK2, new byte[12], handshakeHash, new byte[0]);
            handshakeHash    = SHA256.ComputeHash(handshakeHash.ConcatToNewArray(tag1));

            _state.HandshakeHash  = handshakeHash;
            _state.ChainingKey    = chainingKey;
            _state.TempKey2       = tempK2;
            _state.HandshakeState = HandshakeState.Act2;
            return(ByteExtensions.Combine(new byte[] { 0 }, _state.EphemeralKeyPair.PublicKeyCompressed, tag1));
        }
Beispiel #6
0
        public (byte[] tempK1, ECKeyPair ephemeralKey) ReadActOneRequest(Span <byte> message, int length)
        {
            if (_state.HandshakeState != HandshakeState.Initialized)
            {
                throw new InvalidOperationException($"Invalid handshake state {_state.HandshakeState}. Must be Initialized");
            }

            if (length != 50)
            {
                throw new ArgumentException("ACT1_READ_FAILED");
            }

            byte        version = message.Slice(0, 1)[0];
            ECKeyPair   responderEphemeralKey = new ECKeyPair(message.Slice(1, 33), false);
            Span <byte> c = message.Slice(34, 16);

            if (version != 0)
            {
                throw new NotSupportedException("ACT1_BAD_VERSION");
            }

            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(responderEphemeralKey.PublicKeyCompressed));
            byte[] ss            = ECDH.ComputeHashedPoint(responderEphemeralKey.PublicKeyParameters, _state.LocalKeyPair.PrivateKey);
            (byte[] chainingKey, byte[] tempK1) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);
            _state.ChainingKey = chainingKey;

            (_, byte[] mac) = ChaCha20Poly1305.DecryptWithAdditionalData(tempK1, _state.ReceiveNonce.GetBytes(), handshakeHash, new byte[0]);

            if (!c.SequenceEqual(mac))
            {
                throw new ArgumentException("ACT1_BAD_TAG");
            }

            _state.ReceiveNonce.Increment();
            _state.HandshakeHash  = SHA256.ComputeHash(handshakeHash.ConcatToNewArray(c.ToArray()));
            _state.HandshakeState = HandshakeState.Act1;
            return(tempK1, responderEphemeralKey);
        }
Beispiel #7
0
        public void ReadActThreeRequest(Span <byte> message, int length)
        {
            if (length != 66)
            {
                throw new ArgumentException("ACT3_READ_FAILED");
            }

            byte        version = message.Slice(0, 1)[0];
            Span <byte> c       = message.Slice(1, 49);

            //byte[] t = message.SubArray(50, 16);

            if (version != 0)
            {
                throw new NotSupportedException("ACT3_BAD_VERSION");
            }

            (byte[] rs, _) = ChaCha20Poly1305.DecryptWithAdditionalData(_state.TempKey2, _state.ReceiveNonce.GetBytes(), _state.HandshakeHash, c.ToArray());
            ECKeyPair rsKey = new ECKeyPair(((Span <byte>)rs).Slice(0, 33), false);

            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(c.ToArray()));
            byte[] ss            = ECDH.ComputeHashedPoint(rsKey.PublicKeyParameters, _state.EphemeralKeyPair.PrivateKey);
            (byte[] chainingKey, _) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);

            //byte[] p, byte[] mac2) = ChaCha20Poly1305.decryptWithAD(tempK3, new byte[12], handshakeHash, t);
            // TODO: do mac check

            (byte[] decryptKey, byte[] encryptKey) = HmacSha256.ComputeHashes(chainingKey, new byte[0]);

            _state.ChainingKey          = chainingKey;
            _state.HandshakeHash        = handshakeHash;
            _state.SendEncryptionKey    = encryptKey;
            _state.ReceiveDecryptionKey = decryptKey;
            _state.SendNonce.Reset();
            _state.ReceiveNonce.Reset();
            _state.HandshakeState = HandshakeState.Finished;
        }
Beispiel #8
0
        public byte[] ApplyActThree(byte[] tempK2, ECKeyPair responderEphemeralKey)
        {
            if (_state.HandshakeState != HandshakeState.Act2)
            {
                throw new InvalidOperationException($"Invalid Handshake state {_state.HandshakeState}. Must be Act2");
            }

            (byte[] cipherText, byte[] tag) = ChaCha20Poly1305.EncryptWithAdditionalData(tempK2, _state.SendNonce.GetBytes(), _state.HandshakeHash, _state.LocalKeyPair.PublicKeyCompressed);
            byte[] cipherAndMac  = cipherText.ConcatToNewArray(tag);
            byte[] handshakeHash = SHA256.ComputeHash(_state.HandshakeHash.ConcatToNewArray(cipherAndMac));
            byte[] ss            = ECDH.ComputeHashedPoint(responderEphemeralKey.PublicKeyParameters, _state.LocalKeyPair.PrivateKey);
            (byte[] chainingKey, byte[] tempK3) = HmacSha256.ComputeHashes(_state.ChainingKey, ss);
            (_, byte[] tag2) = ChaCha20Poly1305.EncryptWithAdditionalData(tempK3, new byte[12], handshakeHash, new byte[0]);
            (byte[] encryptKey, byte[] decryptKey) = HmacSha256.ComputeHashes(chainingKey, new byte[0]);

            _state.HandshakeHash        = handshakeHash;
            _state.ChainingKey          = chainingKey;
            _state.SendEncryptionKey    = encryptKey;
            _state.ReceiveDecryptionKey = decryptKey;
            _state.SendNonce.Reset();
            _state.ReceiveNonce.Reset();
            _state.HandshakeState = HandshakeState.Finished;
            return(ByteExtensions.Combine(new byte[] { 0 }, cipherAndMac, tag2));
        }