Esempio n. 1
0
        public static bool MatchMessageToSession(ArraySegment <byte> message, IAesFactory aesfac, IKeyAgreementFactory kexfac, byte[] state)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }
            if (aesfac == null)
            {
                throw new ArgumentNullException(nameof(aesfac));
            }
            if (kexfac == null)
            {
                throw new ArgumentNullException(nameof(kexfac));
            }
            if (state == null)
            {
                throw new ArgumentNullException(nameof(state));
            }
            if (message.Count < MinimumMessageSize)
            {
                throw new ArgumentException("The message is too small to be a valid message", nameof(message));
            }

            using var mem = new MemoryStream(state);
            using var s   = State.Load(mem, kexfac, 32);

            if (s == null)
            {
                return(false);
            }

            if (s != null && s.Ratchets != null && !s.Ratchets.IsEmpty)
            {
                byte[][] keys = new byte[s.Ratchets.Count + 1][];
                for (int i = 0; i < s.Ratchets.Count; i++)
                {
                    keys[i] = s.Ratchets[i].ReceiveHeaderKey;
                    if (i == s.Ratchets.Count - 1)
                    {
                        keys[i + 1] = s.Ratchets[i].NextReceiveHeaderKey;
                    }
                }

                return(MatchMessageWithMac(message, aesfac, keys) >= 0);
            }

            if (s is ServerState ss && ss.FirstReceiveHeaderKey != null)
            {
                return(MatchMessageWithMac(message, aesfac, ss.FirstReceiveHeaderKey) >= 0);
            }

            return(false);
        }
Esempio n. 2
0
        private static int MatchMessageWithMac(ArraySegment <byte> message, IAesFactory aesFactory, params byte[][] keys)
        {
            var messageSize      = message.Count;
            var mac              = new ArraySegment <byte>(message.Array, message.Offset + messageSize - MacSize, MacSize);
            var maciv            = new ArraySegment <byte>(message.Array, message.Offset, 16);
            var payloadExceptMac = new ArraySegment <byte>(message.Array, message.Offset, messageSize - MacSize);

            if (messageSize < MinimumMessageSize)
            {
                return(-1);
            }

            for (int i = 0; i < keys.Length; i++)
            {
                var key = keys[i];
                if (key == null)
                {
                    continue;
                }
                if (key.Length != 32)
                {
                    throw new ArgumentException("Each key must be 32 bytes", nameof(keys));
                }

                var Mac = new Poly(aesFactory);
                Mac.Init(key, maciv, MacSize);
                Mac.Process(payloadExceptMac);
                var compareMac = Mac.Compute();
                if (mac.Matches(compareMac))
                {
                    return(i);
                }
            }

            return(-1);
        }
Esempio n. 3
0
 public static IAes GetAes(this IAesFactory aes, bool forEncryption, byte[] key) =>
 aes.GetAes(forEncryption, new ArraySegment <byte>(key));
Esempio n. 4
0
 public Poly(IAesFactory aesFactory)
 {
     _aesFactory = aesFactory;
 }
Esempio n. 5
0
 public static bool MatchMessageToApplicationKey(ArraySegment <byte> message, IAesFactory aesfac, byte[] applicationKey)
 {
     return(MatchMessageWithMac(message, aesfac, applicationKey) >= 0);
 }
Esempio n. 6
0
 public AesKdf(IAesFactory aesFactory)
 {
     _aesFactory = aesFactory;
 }