Esempio n. 1
0
        /// <summary>
        /// Check the given arguments and throw a <see cref="NetMQSecurityException"/> if something is amiss.
        /// </summary>
        /// <param name="contentType">This identifies the type of content: ChangeCipherSpec, Handshake, or ApplicationData.</param>
        /// <param name="seqNum"></param>
        /// <param name="frameIndex"></param>
        /// <param name="plainBytes"></param>
        /// <param name="mac"></param>
        /// <param name="padding"></param>
        /// <exception cref="NetMQSecurityException"><see cref="NetMQSecurityErrorCode.MACNotMatched"/>: MAC does not match message.</exception>
        public void ValidateBytes(ContentType contentType, ulong seqNum, byte[] plainBytes, byte[] mac, byte[] padding)
        {
            if (SecurityParameters.MACAlgorithm != MACAlgorithm.Null)
            {
                byte[] typeAndVersion = new[] { (byte)contentType, m_SubProtocolVersion[0], m_SubProtocolVersion[1] };
                byte[] seqNumBytes    = BitConverter.GetBytes(seqNum).Reverse().ToArray();
                byte[] messageSize    = BitConverter.GetBytes(plainBytes.Length).Take(2).Reverse().ToArray();
                //byte[] messageSize = plainBytes.LengthToBytes(2);
                m_decryptionHMAC.Initialize();
                m_decryptionHMAC.TransformBlock(seqNumBytes, 0, seqNumBytes.Length, seqNumBytes, 0);
                m_decryptionHMAC.TransformBlock(typeAndVersion, 0, typeAndVersion.Length, typeAndVersion, 0);
                m_decryptionHMAC.TransformBlock(messageSize, 0, messageSize.Length, messageSize, 0);
                m_decryptionHMAC.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
                //MAC(MAC_write_key, seq_num +
                //      TLSCompressed.type +
                //      TLSCompressed.version +
                //      TLSCompressed.length +
                //      TLSCompressed.fragment);
                //where "+" denotes concatenation.
                if (!m_decryptionHMAC.Hash.SequenceEqual(mac))
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.MACNotMatched, "MAC does not match message");
                }

                for (int i = 0; i < padding.Length; i++)
                {
                    if (padding[i] != padding.Length - 1)
                    {
                        throw new NetMQSecurityException(NetMQSecurityErrorCode.MACNotMatched, "MAC not matched message");
                    }
                }
            }
        }
Esempio n. 2
0
        private static byte[] F(string password, Salt salt, int derivationIterations)
        {
            HMAC hmacsha512 = New <HMACSHA512>().Initialize(new SymmetricKey(new UTF8Encoding(false).GetBytes(password)));

            hmacsha512.TransformBlock(salt.GetBytes(), 0, salt.Length, null, 0);
            byte[] iBytes = 1.GetBigEndianBytes();

            hmacsha512.TransformBlock(iBytes, 0, iBytes.Length, null, 0);
            hmacsha512.TransformFinalBlock(_empty, 0, 0);

            byte[] u  = hmacsha512.Hash();
            byte[] un = u;

            for (int c = 2; c <= derivationIterations; ++c)
            {
                hmacsha512.Initialize();
                hmacsha512.TransformBlock(u, 0, u.Length, null, 0);
                hmacsha512.TransformFinalBlock(_empty, 0, 0);
                u = hmacsha512.Hash();
                for (int i = 0; i < u.Length; i++)
                {
                    un[i] ^= u[i];
                }
            }

            return(un);
        }
Esempio n. 3
0
        private byte[] Func()
        {
            byte[] array = Utils_Int(m_block);
            m_hmac.TransformBlock(m_salt, 0, m_salt.Length, null, 0);
            m_hmac.TransformBlock(array, 0, array.Length, null, 0);
            var _EmptyArray_byte_Value = new byte[0];             // EmptyArray<byte>.Value

            m_hmac.TransformFinalBlock(_EmptyArray_byte_Value, 0, 0);
            byte[] hashValue = m_hmac.Hash;
            m_hmac.Initialize();
            byte[] array2 = hashValue;
            for (int i = 2; i <= m_iterations; i++)
            {
                m_hmac.TransformBlock(hashValue, 0, hashValue.Length, null, 0);
                m_hmac.TransformFinalBlock(_EmptyArray_byte_Value, 0, 0);
                hashValue = m_hmac.Hash;
                for (int j = 0; j < m_blockSize; j++)
                {
                    array2[j] ^= hashValue[j];
                }
                m_hmac.Initialize();
            }
            m_block++;
            return(array2);
        }
Esempio n. 4
0
        public void ValidateBytes(ContentType contentType, ulong seqNum, int frameIndex,
                                  byte[] plainBytes, byte[] mac, byte[] padding)
        {
            if (SecurityParameters.MACAlgorithm != MACAlgorithm.Null)
            {
                byte[] versionAndType  = new byte[] { (byte)contentType, m_protocolVersion[0], m_protocolVersion[1] };
                byte[] seqNumBytes     = BitConverter.GetBytes(seqNum);
                byte[] messageSize     = BitConverter.GetBytes(plainBytes.Length);
                byte[] frameIndexBytes = BitConverter.GetBytes(frameIndex);

                m_decryptionHMAC.Initialize();
                m_decryptionHMAC.TransformBlock(seqNumBytes, 0, seqNumBytes.Length, seqNumBytes, 0);
                m_decryptionHMAC.TransformBlock(versionAndType, 0, versionAndType.Length, versionAndType, 0);
                m_decryptionHMAC.TransformBlock(messageSize, 0, messageSize.Length, messageSize, 0);
                m_decryptionHMAC.TransformBlock(frameIndexBytes, 0, frameIndexBytes.Length, frameIndexBytes, 0);
                m_decryptionHMAC.TransformFinalBlock(plainBytes, 0, plainBytes.Length);

                if (!m_decryptionHMAC.Hash.SequenceEqual(mac))
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.MACNotMatched, "MAC not matched message");
                }

                for (int i = 0; i < padding.Length; i++)
                {
                    if (padding[i] != padding.Length - 1)
                    {
                        throw new NetMQSecurityException(NetMQSecurityErrorCode.MACNotMatched, "MAC not matched message");
                    }
                }
            }
        }
Esempio n. 5
0
        protected void VerifyHmac(
            int testCaseId,
            string digest,
            int truncateSize = -1)
        {
            byte[] digestBytes = ByteUtils.HexToByteArray(digest);
            byte[] data        = _testData[testCaseId];
            byte[] computedDigest;

            using (HMAC hmac = Create())
            {
                Assert.True(hmac.HashSize > 0);

                byte[] key = (byte[])_testKeys[testCaseId].Clone();
                hmac.Key = key;

                // make sure the getter returns different objects each time
                Assert.NotSame(key, hmac.Key);
                Assert.NotSame(hmac.Key, hmac.Key);

                // make sure the setter didn't cache the exact object we passed in
                key[0] = (byte)(key[0] + 1);
                Assert.NotEqual <byte>(key, hmac.Key);

                computedDigest = hmac.ComputeHash(data);
            }

            if (truncateSize != -1)
            {
                byte[] tmp = new byte[truncateSize];
                Array.Copy(computedDigest, tmp, truncateSize);
                computedDigest = tmp;
            }

            Assert.Equal(digestBytes, computedDigest);

            using (HMAC hmac = Create())
            {
                byte[] key = (byte[])_testKeys[testCaseId].Clone();
                hmac.Key = key;

                hmac.TransformBlock(data, 0, data.Length, null, 0);
                hmac.Initialize();
                hmac.TransformBlock(data, 0, data.Length, null, 0);
                hmac.TransformFinalBlock(Array.Empty <byte>(), 0, 0);
                computedDigest = hmac.Hash;
            }

            if (truncateSize != -1)
            {
                byte[] tmp = new byte[truncateSize];
                Array.Copy(computedDigest, tmp, truncateSize);
                computedDigest = tmp;
            }

            Assert.Equal(digestBytes, computedDigest);
        }
Esempio n. 6
0
        private byte[] EncryptBytes(ICryptoTransform encryptor, ContentType contentType, ulong seqNum,
                                    int frameIndex, byte[] plainBytes)
        {
            byte[] mac;

            if (SecurityParameters.MACAlgorithm != MACAlgorithm.Null)
            {
                byte[] versionAndType  = new byte[] { (byte)contentType, m_protocolVersion[0], m_protocolVersion[1] };
                byte[] seqNumBytes     = BitConverter.GetBytes(seqNum);
                byte[] messageSize     = BitConverter.GetBytes(plainBytes.Length);
                byte[] frameIndexBytes = BitConverter.GetBytes(frameIndex);

                m_encryptionHMAC.Initialize();
                m_encryptionHMAC.TransformBlock(seqNumBytes, 0, seqNumBytes.Length, seqNumBytes, 0);
                m_encryptionHMAC.TransformBlock(versionAndType, 0, versionAndType.Length, versionAndType, 0);
                m_encryptionHMAC.TransformBlock(messageSize, 0, messageSize.Length, messageSize, 0);
                m_encryptionHMAC.TransformBlock(frameIndexBytes, 0, frameIndexBytes.Length, frameIndexBytes, 0);
                m_encryptionHMAC.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
                mac = m_encryptionHMAC.Hash;
            }
            else
            {
                mac = new byte[0];
            }

            int  length  = plainBytes.Length + SecurityParameters.MACLength;
            byte padding = 0;

            if (SecurityParameters.BulkCipherAlgorithm != BulkCipherAlgorithm.Null)
            {
                padding = (byte)((encryptor.OutputBlockSize -
                                  (plainBytes.Length + SecurityParameters.MACLength + 1) % encryptor.OutputBlockSize) %
                                 encryptor.OutputBlockSize);

                length += padding + 1;
            }

            byte[] cipherBytes = new byte[length];

            Buffer.BlockCopy(plainBytes, 0, cipherBytes, 0, plainBytes.Length);
            Buffer.BlockCopy(mac, 0, cipherBytes, plainBytes.Length, SecurityParameters.MACLength);

            if (SecurityParameters.BulkCipherAlgorithm != BulkCipherAlgorithm.Null)
            {
                for (int i = plainBytes.Length + SecurityParameters.MACLength; i < cipherBytes.Length; i++)
                {
                    cipherBytes[i] = padding;
                }

                encryptor.TransformBlock(cipherBytes, 0, cipherBytes.Length, cipherBytes, 0);
            }

            return(cipherBytes);
        }
Esempio n. 7
0
        protected void VerifyHmac(int testCaseId, byte[] digestBytes)
        {
            byte[] data = _testData[testCaseId];
            byte[] computedDigest;
            int    truncateSize = digestBytes.Length;

            AssertExtensions.LessThanOrEqualTo(truncateSize, MacSize);

            using (HMAC hmac = Create())
            {
                Assert.Equal(MacSize, hmac.HashSize / 8);

                byte[] key = (byte[])_testKeys[testCaseId].Clone();
                hmac.Key = key;

                // make sure the getter returns different objects each time
                Assert.NotSame(key, hmac.Key);
                Assert.NotSame(hmac.Key, hmac.Key);

                // make sure the setter didn't cache the exact object we passed in
                key[0] = (byte)(key[0] + 1);
                Assert.NotEqual <byte>(key, hmac.Key);

                computedDigest = hmac.ComputeHash(data);
            }

            computedDigest = Truncate(computedDigest, truncateSize);
            Assert.Equal(digestBytes, computedDigest);

            using (HMAC hmac = Create())
            {
                byte[] key = (byte[])_testKeys[testCaseId].Clone();
                hmac.Key = key;

                hmac.TransformBlock(data, 0, data.Length, null, 0);
                hmac.Initialize();
                hmac.TransformBlock(data, 0, data.Length, null, 0);
                hmac.TransformFinalBlock(Array.Empty <byte>(), 0, 0);
                computedDigest = hmac.Hash;
            }

            computedDigest = Truncate(computedDigest, truncateSize);
            Assert.Equal(digestBytes, computedDigest);

            // One shot - allocating and byte array inputs
            computedDigest = HashDataOneShot(_testKeys[testCaseId], data);

            computedDigest = Truncate(computedDigest, truncateSize);
            Assert.Equal(digestBytes, computedDigest);
Esempio n. 8
0
        // This function is defined as follow :
        // Func (S, i) = HMAC(S || i) | HMAC2(S || i) | ... | HMAC(iterations) (S || i)
        // where i is the block number.
        byte[] Func()
        {
            var intBlock = UintToBigEndianBytes(_block);

            _hmac.TransformBlock(_salt, 0, _salt.Length, _salt, 0);
            _hmac.TransformFinalBlock(intBlock, 0, intBlock.Length);
            var temp = _hmac.Hash;

            _hmac.Initialize();

            var ret = temp;

            for (var i = 2; i <= _iterations; i++)
            {
                temp = _hmac.ComputeHash(temp);
                for (var j = 0; j < BlockSize; j++)
                {
                    ret[j] ^= temp[j];
                }
            }

            // increment the block count.
            _block++;
            return(ret);
        }
Esempio n. 9
0
        private static async Task <byte[]> ComputeRequestBodyHmacHashAsync(HttpRequest request, HMAC hasher)
        {
            await PrepareRequestBody(request);

            try
            {
                Stream inputStream = request.Body;

                int    bytesRead;
                byte[] buffer = new byte[4096];

                while ((bytesRead = await inputStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                {
                    hasher.TransformBlock(buffer, inputOffset: 0, inputCount: bytesRead, outputBuffer: null, outputOffset: 0);
                }

                hasher.TransformFinalBlock(Array.Empty <byte>(), inputOffset: 0, inputCount: 0);

                return(hasher.Hash);
            }
            finally
            {
                request.Body.Seek(0L, SeekOrigin.Begin);
            }
        }
        public void AppendData(byte[] data)
        {
            if (_hmac == null)
            {
                throw new ObjectDisposedException("IncrementalHash");
            }

            _hmac.TransformBlock(data, 0, data.Length, data, 0);
        }
Esempio n. 11
0
            internal AesCbcHmacSha2Decryptor(string name, byte[] key, byte[] iv, byte[] associatedData)
            {
                // Split the key to get the AES key, the HMAC key and the HMAC object
                byte[] aesKey;

                GetAlgorithmParameters(name, key, out aesKey, out _hmac_key, out _hmac);

                // Create the AES provider
                _aes = new RijndaelManaged {
                    Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7, KeySize = aesKey.Length * 8, Key = aesKey, IV = iv
                };

                _inner = _aes.CreateDecryptor();

                _associated_data_length = ConvertToBigEndian(associatedData.Length * 8);

                // Prime the hash.
                _hmac.TransformBlock(associatedData, 0, associatedData.Length, associatedData, 0);
                _hmac.TransformBlock(iv, 0, iv.Length, iv, 0);
            }
Esempio n. 12
0
 public void CheckE(string testName, HMAC algo, byte[] data, byte[] result)
 {
     byte[] copy = new byte[data.Length];
     for (int i = 0; i < data.Length - 1; i++)
     {
         algo.TransformBlock(data, i, 1, copy, i);
     }
     algo.TransformFinalBlock(data, data.Length - 1, 1);
     Compare(result, algo.Hash, testName + "e");
     algo.Initialize();
 }
Esempio n. 13
0
        public static byte[] ComputeHash(this HMAC hmac, params byte[][] blobs)
        {
            hmac.Initialize();
            // TODO: generalize to allow encodings other than UTF-8.
            foreach (var blob in blobs.Take(blobs.Length - 1))
            {
                hmac.TransformBlock(blob, 0, blob.Length, null, 0);
            }
            var lastBlob = blobs[blobs.Length - 1];

            hmac.TransformFinalBlock(lastBlob, 0, lastBlob.Length);
            return(hmac.Hash);
        }
Esempio n. 14
0
        static byte[] Compute_PHash(int bytes, byte[][] seeds, HMAC hmac, int blockSize)
        {
            int blocks = (bytes / blockSize) + (bytes % blockSize == 0 ? 0 : 1);

            byte[] ret  = new byte[blockSize * blocks];
            byte[] prev = null;

            for (int i = 0; i < blocks; i++)
            {
                hmac.Initialize();
                if (prev == null)
                {
                    for (int q = 0; q < seeds.Length; q++)
                    {
                        hmac.TransformBlock(seeds[q], 0, seeds[q].Length, seeds[q], 0);
                    }
                }
                else
                {
                    hmac.TransformBlock(prev, 0, prev.Length, prev, 0);
                }
                hmac.TransformFinalBlock(Utility.EmptyByteArray, 0, 0);
                prev = hmac.Hash;
                hmac.Initialize();
                hmac.TransformBlock(prev, 0, prev.Length, prev, 0);
                for (int q = 0; q < seeds.Length; q++)
                {
                    hmac.TransformBlock(seeds[q], 0, seeds[q].Length, seeds[q], 0);
                }
                hmac.TransformFinalBlock(Utility.EmptyByteArray, 0, 0);
                for (int q = 0; q < blockSize; q++)
                {
                    ret[i * blockSize + q] = hmac.Hash[q];
                }
            }
            return(ret);
        }
Esempio n. 15
0
        public string CreateSignature(Message message)
        {
            var messages = GetMessagesToAddForDigest(message);

            // For all items update the signature
            foreach (var item in messages)
            {
                var sourceBytes = _encoder.GetBytes(item);
                _signatureGenerator.TransformBlock(sourceBytes, 0, sourceBytes.Length, null, 0);
            }

            _signatureGenerator.TransformFinalBlock(new byte[0], 0, 0);

            // Calculate the digest and remove -
            return(BitConverter.ToString(_signatureGenerator.Hash).Replace("-", "").ToLower());
        }
Esempio n. 16
0
		static readonly byte[] emptyArray64 = new byte[64]; // for SHA-512

		public HKDF(Func<HMAC> hmacFactory, byte[] ikm, byte[] salt = null, byte[] context = null)
		{
			hmac = hmacFactory();
			hmac2 = hmac as HMAC2;
			hashLength = hmac.HashSize >> 3;

			// a malicious implementation of HMAC could conceivably mess up the shared static empty byte arrays, which are still writeable...
			hmac.Key = salt ?? (hashLength == 48 ? emptyArray48 : hashLength == 64 ? emptyArray64 : hashLength == 32 ? emptyArray32 : hashLength == 20 ? emptyArray20 : new byte[hashLength]);

			// re-keying hmac with PRK
			hmac.TransformBlock(ikm, 0, ikm.Length, null, 0);
			hmac.TransformFinalBlock(ikm, 0, 0);
			hmac.Key = (hmac2 != null) ? hmac2.HashInner : hmac.Hash;
			hmac.Initialize();
			this.context = context;
			Reset();
		}
Esempio n. 17
0
        /// <summary>
        /// Creates the signature.
        /// </summary>
        /// <returns>The signature.</returns>
        /// <param name="message">Message.</param>
        public string CreateSignature(Message message)
        {
            this._signatureGenerator.Initialize();

            List <string> messages = this.GetDigestMessages(message);

            // For all items update the signature
            foreach (string item in messages)
            {
                byte[] sourceBytes = this._encoder.GetBytes(item);
                _signatureGenerator.TransformBlock(sourceBytes, 0, sourceBytes.Length, null, 0);
            }

            _signatureGenerator.TransformFinalBlock(new byte[0], 0, 0);

            // Calculate the digest and remove -
            return(BitConverter.ToString(_signatureGenerator.Hash).Replace("-", "").ToLower());
        }
Esempio n. 18
0
        /// <summary>
        /// Creates the signature.
        /// </summary>
        /// <returns>The signature.</returns>
        /// <param name="message">Message.</param>
        public string CreateSignature(params string[] messages)
        {
            byte[] sourceBytes;
            _signatureGenerator.Initialize();
            // For all items update the signature
            var last = messages.Length - 1;

            for (var i = 0; i < last; i++)
            {
                sourceBytes = this._encoder.GetBytes(messages[i]);
                _signatureGenerator.TransformBlock(sourceBytes, 0, sourceBytes.Length, null, 0);
            }

            sourceBytes = _encoder.GetBytes(messages[last]);
            _signatureGenerator.TransformFinalBlock(sourceBytes, 0, sourceBytes.Length);

            // Calculate the digest and remove -
            return(BitConverter.ToString(_signatureGenerator.Hash).Replace("-", "").ToLower());
        }
Esempio n. 19
0
        private byte[] GetSHA1Bytes(int count)
        {
            byte[] ret = new byte[count];

            int filled = 0;

            while (filled < ret.Length)
            {
                if (filled + _sha1Hash.Length < count)
                {
                    /* Copy current hash into results */
                    Array.Copy(_sha1Hash, 0, ret, filled, _sha1Hash.Length);
                    filled += _sha1Hash.Length;

                    /* Calculate the next hash */
                    _sha1HMAC.Initialize();
                    _sha1HMAC.TransformBlock(_sha1Ai, 0, _sha1HMAC.HashSize / 8, _sha1Ai, 0);
                    _sha1HMAC.TransformFinalBlock(_seed, 0, _seed.Length);
                    _sha1Hash = _sha1HMAC.Hash;

                    _sha1HMAC.Initialize();
                    _sha1Ai = _sha1HMAC.ComputeHash(_sha1Ai);
                }
                else
                {
                    /* Count how many bytes to consume */
                    int consumed = count - filled;

                    /* Make a partial copy of the current hash */
                    Array.Copy(_sha1Hash, 0, ret, filled, consumed);
                    filled += consumed;

                    /* Remove read bytes from the current hash */
                    byte[] tmp = new byte[_sha1Hash.Length - consumed];
                    Array.Copy(_sha1Hash, _sha1Hash.Length - tmp.Length, tmp, 0, tmp.Length);
                    _sha1Hash = tmp;
                }
            }

            return(ret);
        }
Esempio n. 20
0
        // iterative hash function
        private byte[] Func()
        {
            byte[] INT_block = _block.GetBigEndianBytes();

            _hmac.TransformBlock(_salt, 0, _salt.Length, _salt, 0);
            _hmac.TransformFinalBlock(INT_block, 0, INT_block.Length);
            byte[] temp = _hmac.Hash;
            _hmac.Initialize();

            byte[] ret = temp;
            for (int i = 2; i <= _iterationCount; i++)
            {
                temp = _hmac.ComputeHash(temp);
                for (int j = 0; j < _blockSize; j++)
                {
                    ret[j] ^= temp[j];
                }
            }

            _block++;
            return(ret);
        }
        private byte[] ComputeBlock(int block, int size)
        {
            byte[] inputBuffer = BitConverter.GetBytes(block);
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(inputBuffer, 0, 4);
            }

            _hashAlgo.TransformBlock(_salt, 0, _salt.Length, _salt, 0);
            _hashAlgo.TransformFinalBlock(inputBuffer, 0, inputBuffer.Length);
            byte[] hash = _hashAlgo.Hash;
            _hashAlgo.Initialize();

            byte[] result = hash;
            for (int i = 2; i <= _iterations; i++)
            {
                hash = _hashAlgo.ComputeHash(hash);
                for (int j = 0; j < size; j++)
                {
                    result[j] = (byte)(result[j] ^ hash[j]);
                }
            }
            return(result);
        }
Esempio n. 22
0
            public byte[] GetBytes()
            {
                int         curLen = 0;
                List <byte> temp   = new List <byte>();

                if (this.cssl.cipherObj.GetEncMode() == "CBC")
                {
                    String macAlg  = this.cssl.cipherObj.GetHmacAlg();
                    HMAC   hashObj = this.cssl.GetHmacObj(macAlg, this.cssl.client_write_MAC_secret);

                    byte[] hs1 = new byte[this.seqNum.Length];
                    byte[] hs2 = new byte[1];
                    byte[] hs3 = new byte[1];
                    byte[] hs4 = new byte[1];
                    byte[] hs5 = new byte[this.record_len.Length];
                    byte[] hs6 = new byte[this.record.Length];

                    Array.Copy(this.seqNum, 0, hs1, 0, this.seqNum.Length);
                    if (this.handshake)
                    {
                        hs2[0] = 22;
                    }
                    else
                    {
                        hs2[0] = 23;
                    }
                    hs3[0] = this.major;
                    hs4[0] = this.minor;
                    Array.Copy(this.record_len, 0, hs5, 0, this.record_len.Length);
                    Array.Copy(this.record, 0, hs6, 0, this.record.Length);

                    hashObj.TransformBlock(hs1, 0, hs1.Length, hs1, 0);
                    hashObj.TransformBlock(hs2, 0, hs2.Length, hs2, 0);
                    hashObj.TransformBlock(hs3, 0, hs3.Length, hs3, 0);
                    hashObj.TransformBlock(hs4, 0, hs4.Length, hs4, 0);
                    hashObj.TransformBlock(hs5, 0, hs5.Length, hs5, 0);
                    hashObj.TransformFinalBlock(hs6, 0, hs6.Length);

                    this.mac = new byte[hashObj.HashSize / 8];
                    Array.Copy(hashObj.Hash, 0, this.mac, 0, hashObj.Hash.Length);

                    curLen = this.record.Length + this.mac.Length + 1;
                    int blockLen;
                    if (this.handshake)
                    {
                        blockLen = 16;
                    }
                    else
                    {
                        blockLen = this.cssl.client_write_IV.Length;
                    }
                    int padLen = blockLen - (curLen % blockLen);
                    if (padLen == blockLen)
                    {
                        padLen = 0;
                    }

                    if (padLen != 0)
                    {
                        this.padding_list = new List <byte>();

                        for (int i = 0; i < padLen + 1; i++)
                        {
                            this.padding_list.Add((byte)padLen);
                        }
                        this.padding = this.padding_list.ToArray();
                    }

                    temp.AddRange(this.R);
                    temp.AddRange(this.record);
                    temp.AddRange(this.mac);

                    if (padLen != 0)
                    {
                        temp.AddRange(this.padding);
                    }
                    this.finalPacket = new byte[temp.Count];
                    Array.Copy(temp.ToArray(), 0, this.finalPacket, 0, temp.Count);

                    this.encHS = this.cssl.enc.AES_Encrypt(this.finalPacket, this.cssl.client_write_key, this.cssl.client_write_IV,
                                                           this.cssl.cipherObj.GetEncMode(), this.cssl.cipherObj.GetKeySize());
                }
                else if (this.cssl.cipherObj.GetEncMode() == "GCM")
                {
                    UInt64 seqNum = 0L;
                    byte   ctype;
                    if (this.handshake)
                    {
                        ctype = 22;
                    }
                    else
                    {
                        ctype = 23;
                    }
                    int ks = this.cssl.cipherObj.GetKeySize();
                    this.cssl.common.pythonFormat = 1;
                    this.encHS = this.cssl.enc.AES_Encrypt_GCM(this.cssl.client_write_key, this.cssl.client_write_IV, this.record, seqNum_UInt, ctype, ks, this.cssl.common);
                    this.cssl.common.pythonFormat = 0;
                }

                temp.Clear();
                temp.TrimExcess();
                if (this.handshake)
                {
                    temp.Add((byte)22);
                }
                else
                {
                    temp.Add((byte)23);
                }
                temp.Add(this.major);
                temp.Add(this.minor);

                byte[] encLen = BitConverter.GetBytes((short)this.encHS.Length);

                Array.Reverse(encLen);
                temp.AddRange(encLen);
                temp.AddRange(this.encHS);

                this.encRec = temp.ToArray();

                return(this.encRec);
            }
Esempio n. 23
0
        private byte[] EncryptBytes(ICryptoTransform encryptor, ContentType contentType, ulong seqNum, byte[] plainBytes)
        {
            byte[] mac;
            //记录有效负载保护
            //加密和 MAC 功能将 TLS 压缩结构转换为 TLSCipher 文本。 解密功能反转该过程。
            //记录的 MAC 还包括一个序列号,以便可检测到缺失、额外或重复的消息。
            //  struct {
            //       ContentType type;
            //        ProtocolVersion version;
            //        uint16 length;
            //        opaque fragment[TLSPlaintext.length];
            //    }
            //    TLSPlaintext;
            if (SecurityParameters.MACAlgorithm != MACAlgorithm.Null)
            {
                byte[] versionAndType = new[] { (byte)contentType, m_SubProtocolVersion[0], m_SubProtocolVersion[1] };
                byte[] seqNumBytes    = BitConverter.GetBytes(seqNum).Reverse().ToArray();                            //大端
                byte[] messageSize    = BitConverter.GetBytes((ushort)plainBytes.Length).Take(2).Reverse().ToArray(); //长度2字节

                m_encryptionHMAC.Initialize();
                m_encryptionHMAC.TransformBlock(seqNumBytes, 0, seqNumBytes.Length, seqNumBytes, 0);
                m_encryptionHMAC.TransformBlock(versionAndType, 0, versionAndType.Length, versionAndType, 0);
                m_encryptionHMAC.TransformBlock(messageSize, 0, messageSize.Length, messageSize, 0);
                m_encryptionHMAC.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
                mac = m_encryptionHMAC.Hash;
            }
            else
            {
                mac = EmptyArray <byte> .Instance;
            }

            int  length  = plainBytes.Length + SecurityParameters.MACLength;
            byte padding = 0;

            if (SecurityParameters.BulkCipherAlgorithm != BulkCipherAlgorithm.Null)
            {
                padding = (byte)((encryptor.OutputBlockSize -
                                  (plainBytes.Length + SecurityParameters.MACLength + 1) % encryptor.OutputBlockSize) %
                                 encryptor.OutputBlockSize);

                length += padding + 1;
            }

            byte[] cipherBytes = new byte[length];

            Buffer.BlockCopy(plainBytes, 0, cipherBytes, 0, plainBytes.Length);
            Buffer.BlockCopy(mac, 0, cipherBytes, plainBytes.Length, SecurityParameters.MACLength);
#if DEBUG
            Debug.WriteLine("[TLSPlaintext]:" + BitConverter.ToString(cipherBytes));
            Debug.WriteLine("[TLSPlaintext.data]:" + BitConverter.ToString(plainBytes));
            Debug.WriteLine("[TLSPlaintext.mac]:" + BitConverter.ToString(mac));
            Debug.WriteLine("[TLSPlaintext.padding]:" + padding);
#endif
            if (SecurityParameters.BulkCipherAlgorithm != BulkCipherAlgorithm.Null)
            {
                for (int i = plainBytes.Length + SecurityParameters.MACLength; i < cipherBytes.Length; i++)
                {
                    cipherBytes[i] = padding;
                }

                encryptor.TransformBlock(cipherBytes, 0, cipherBytes.Length, cipherBytes, 0);
            }
            return(cipherBytes);
        }
Esempio n. 24
0
        TLSMessage ReadCipherText(ContentType type, ProtocolVersion ver, int offset, ushort length)
        {
            if (ver == ProtocolVersion.TLS11 && ver == ProtocolVersion.TLS12)
            {
                throw new NotImplementedException();
            }

            Console.WriteLine("Encrypted");
            Utility.Dump(_recvBuffer, offset, length);

            int decrypted = 0;

            while (decrypted < length)
            {
                int tmp = _decryptor.TransformBlock(_recvBuffer, offset + decrypted, length - decrypted, _recvBuffer, decrypted);
                if (tmp == 0)
                {
                    throw new CryptographicException();
                }
                decrypted += tmp;
            }
            Console.WriteLine("Decrypted");
            Utility.Dump(_recvBuffer, 0, length);

            int fragLen = length - _recvBuffer[length - 1] - _sparams.MACLength - 1;

            if (fragLen < 0)
            {
                throw new Exception();                           // Decrypt Error
            }
            Console.WriteLine("Fragment");
            Utility.Dump(_recvBuffer, 0, fragLen);

            Console.WriteLine("HMAC");
            Utility.Dump(_recvBuffer, fragLen, _sparams.MACLength);

            _recvHMAC.Initialize();
            if (_ver == ProtocolVersion.SSL30)
            {
                byte[] temp = new byte[11];
                BitConverterBE.WriteUInt64(_recvSeq, temp, 0);
                temp[8] = (byte)type;
                BitConverterBE.WriteUInt16((ushort)fragLen, temp, 9);
                _recvHMAC.TransformBlock(temp, 0, temp.Length, temp, 0);
            }
            else
            {
                byte[] temp = new byte[13];
                BitConverterBE.WriteUInt64(_recvSeq, temp, 0);
                temp[8] = (byte)type;
                BitConverterBE.WriteUInt16((ushort)ver, temp, 9);
                BitConverterBE.WriteUInt16((ushort)fragLen, temp, 11);
                _recvHMAC.TransformBlock(temp, 0, temp.Length, temp, 0);
            }
            _recvHMAC.TransformBlock(_recvBuffer, 0, fragLen, _recvBuffer, 0);
            _recvHMAC.TransformFinalBlock(Utility.EmptyByteArray, 0, 0);

            Console.WriteLine("Comaputed HMAC");
            Utility.Dump(_recvHMAC.Hash);

            _recvSeq++;

            return(ReadPlainText(type, ver, 0, (ushort)fragLen));
        }