예제 #1
0
        private static byte[] Sign(Smb2CryptoInfo cryptoInfo, Smb2SinglePacket original, Smb2Role role)
        {
            if (Smb2Utility.IsSmb2Family(cryptoInfo.Dialect))
            {
                // [MS-SMB2] 3.1.4.1
                // 3. If Connection.Dialect is "2.002" or "2.100", the sender MUST compute a 32-byte hash using HMAC-SHA256 over the entire message,
                HMACSHA256 hmacSha = new HMACSHA256(cryptoInfo.SigningKey);
                return(hmacSha.ComputeHash(original.ToBytes()));
            }
            else if (cryptoInfo.SigningId == SigningAlgorithm.AES_GMAC)
            {
                // [MS-SMB2] 3.1.4.1
                // 1. If Connection.Dialect belongs to the SMB 3.x dialect family and Connection.SigningAlgorithmId is AES-GMAC,
                // compute a 16-byte hash using the AES-GMAC over the entire message using nonce as specified
                var nonce = Smb2Utility.ComputeNonce(original, role);
                var(_, tag) = AesGmac.ComputeHash(cryptoInfo.SigningKey, nonce, original.ToBytes());

                return(tag);
            }
            else
            {
                // [MS-SMB2] 3.1.4.1
                // 2. If Connection.Dialect belongs to the SMB 3.x dialect family, the sender MUST compute a 16-byte hash using AES-128-CMAC over the entire message
                return(AesCmac128.ComputeHash(cryptoInfo.SigningKey, original.ToBytes()));
            }
        }
        /// <summary>
        /// Verify the signature of a Smb2SinglePacket
        /// </summary>
        /// <param name="packet">The packet to be verified</param>
        /// <param name="cryptoInfo">The cryptoInfo of smb2client</param>
        /// <returns>True when signature verification succeeds and false when fails</returns>
        private bool VerifySignature(Smb2SinglePacket packet, Smb2CryptoInfo cryptoInfo)
        {
            if (cryptoInfo.DisableVerifySignature)
            {
                // Skip the verification.
                return(true);
            }

            try
            {
                if (IsErrorPacket(packet.Header))
                {
                    packet = packet.Error;
                }
                //save the 16-byte signature from the Signature field in the SMB2 Header
                byte[] originalSignature = packet.Header.Signature;

                //zero out the 16-byte signature field in the SMB2 Header of the incoming message.
                packet.Header.Signature = new byte[Smb2Consts.SignatureSize];
                byte[] bytesToCompute = packet.ToBytes();

                //Compute the message with signing key
                byte[] computedSignature = new byte[] { };
                if (Smb2Utility.IsSmb3xFamily(cryptoInfo.Dialect))
                {
                    //[MS-SMB2] 3.1.5.1
                    //If Session.Connection.Dialect belongs to the SMB 3.x dialect family,
                    //the receiver MUST compute a 16-byte hash by using AES-128-CMAC over the entire message,
                    //beginning with the SMB2 Header from step 2, and using the key provided.
                    //The AES-128-CMAC is specified in [RFC4493].

                    //TD has mentioned to use Session.SigningKey for SESSION_SETUP Response and Channel.SigningKey for other responses
                    //In the current SDK, the SigningKey is the Channel.SigningKey
                    computedSignature = AesCmac128.ComputeHash(cryptoInfo.SigningKey, bytesToCompute);
                }
                else
                {
                    //[MS-SMB2] 3.1.5.1
                    //If Session.Connection.Dialect is "2.002" or "2.100", the receiver MUST compute a 32-byte hash by using HMAC-SHA256 over the entire message,
                    //beginning with the SMB2 Header from step 2, and using the key provided.
                    //The HMAC-SHA256 hash is specified in [FIPS180-2] and [RFC2104].

                    HMACSHA256 hmacSha = new HMACSHA256(cryptoInfo.SigningKey);
                    computedSignature = hmacSha.ComputeHash(bytesToCompute);
                }
                packet.Header.Signature = originalSignature;

                //[MS-SMB2] 3.1.5.1
                //If the first 16 bytes (the high-order portion) of the computed signature from step 3 or step 4 matches the saved signature from step 1, the message is signed correctly
                // compare the first 16 bytes of the originalSignature and computedSignature
                return(originalSignature.SequenceEqual(computedSignature.Take(16)));
            }
            catch (Exception ex)
            {
                throw new Exception("Error happened during signature verification of packet: " + packet.ToString() + ". Exception message: " + ex.Message);
            }
        }
 private static byte[] Sign(Smb2CryptoInfo cryptoInfo, byte[] original)
 {
     if (Smb2Utility.IsSmb2Family(cryptoInfo.Dialect))
     {
         // [MS-SMB2] 3.1.4.1
         // 3. If Connection.Dialect is "2.002" or "2.100", the sender MUST compute a 32-byte hash using HMAC-SHA256 over the entire message,
         HMACSHA256 hmacSha = new HMACSHA256(cryptoInfo.SigningKey);
         return(hmacSha.ComputeHash(original));
     }
     else
     {
         // [MS-SMB2] 3.1.4.1
         // 2. If Connection.Dialect belongs to the SMB 3.x dialect family, the sender MUST compute a 16-byte hash using AES-128-CMAC over the entire message
         return(AesCmac128.ComputeHash(cryptoInfo.SigningKey, original));
     }
 }
예제 #4
0
        public static void SignByteArray(Smb2CryptoInfo cryptoInfo, byte[] original, out byte[] nonce, out byte[] signature, Smb2Role role, Smb2Command smb2Command, UInt64 messageId = 1)
        {
            if (Smb2Utility.IsSmb2Family(cryptoInfo.Dialect))
            {
                // [MS-SMB2] 3.1.4.1
                // 3. If Connection.Dialect is "2.02" or "2.1", the sender MUST compute a 32-byte hash using HMAC-SHA256 over the entire message,
                HMACSHA256 hmacSha = new HMACSHA256(cryptoInfo.SigningKey);
                signature = hmacSha.ComputeHash(original);
                nonce     = Array.Empty <byte>();
            }
            else if (Smb2Utility.IsSmb3xFamily(cryptoInfo.Dialect))
            {
                if (cryptoInfo.SigningId == SigningAlgorithm.AES_GMAC)
                {
                    // [MS-SMB2] 3.1.4.1
                    // 1. If Connection.Dialect belongs to the SMB 3.x dialect family and Connection.SigningAlgorithmId is AES-GMAC,
                    // compute a 16-byte hash using the AES-GMAC over the entire message using nonce as specified
                    nonce       = Smb2Utility.ComputeNonce(messageId, role, smb2Command);
                    var(_, tag) = AesGmac.ComputeHash(cryptoInfo.SigningKey, nonce, original);

                    signature = tag;
                }
                else
                {
                    // [MS-SMB2] 3.1.4.1
                    // 2. If Connection.Dialect belongs to the SMB 3.x dialect family, the sender MUST compute a 16-byte hash using AES-128-CMAC over the entire message
                    signature = AesCmac128.ComputeHash(cryptoInfo.SigningKey, original);
                    nonce     = Array.Empty <byte>();
                }
            }
            else
            {
                nonce     = Array.Empty <byte>();
                signature = Array.Empty <byte>();
            }
        }
예제 #5
0
        /// <summary>
        /// Verify the signature of a Smb2SinglePacket
        /// </summary>
        /// <param name="packet">The packet to be verified</param>
        /// <param name="cryptoInfo">The cryptoInfo of smb2client</param>
        /// <returns>True when signature verification succeeds and false when fails</returns>
        private bool VerifySignature(Smb2SinglePacket packet, Smb2CryptoInfo cryptoInfo, byte[] messageBytes)
        {
            if (cryptoInfo.DisableVerifySignature)
            {
                // Skip the verification.
                return(true);
            }

            try
            {
                if (IsErrorPacket(packet.Header))
                {
                    packet = packet.Error;
                }

                byte[] bytesToCompute = messageBytes;
                // Zero out the 16-byte signature field in the SMB2 Header of the incoming message.
                Array.Clear(bytesToCompute, System.Runtime.InteropServices.Marshal.SizeOf(packet.Header) - Smb2Consts.SignatureSize, Smb2Consts.SignatureSize);

                //Compute the message with signing key
                byte[] computedSignature = null;
                if (Smb2Utility.IsSmb3xFamily(cryptoInfo.Dialect))
                {
                    //[MS-SMB2] 3.1.5.1
                    //If Session.Connection.Dialect belongs to the SMB 3.x dialect family,
                    //the receiver MUST compute a 16-byte hash by using AES-128-CMAC over the entire message,
                    //beginning with the SMB2 Header from step 2, and using the key provided.
                    //The AES-128-CMAC is specified in [RFC4493].

                    //TD has mentioned to use Session.SigningKey for SESSION_SETUP Response and Channel.SigningKey for other responses
                    //In the current SDK, the SigningKey is the Channel.SigningKey

                    if (cryptoInfo.SigningId == SigningAlgorithm.AES_GMAC)
                    {
                        var nonce = Smb2Utility.ComputeNonce(packet, this.decodeRole);
                        var(_ciphertext, tag) = AesGmac.ComputeHash(cryptoInfo.SigningKey, nonce, bytesToCompute);

                        computedSignature = tag;
                    }
                    else
                    {
                        computedSignature = AesCmac128.ComputeHash(cryptoInfo.SigningKey, bytesToCompute);
                    }
                }
                else
                {
                    //[MS-SMB2] 3.1.5.1
                    //If Session.Connection.Dialect is "2.002" or "2.100", the receiver MUST compute a 32-byte hash by using HMAC-SHA256 over the entire message,
                    //beginning with the SMB2 Header from step 2, and using the key provided.
                    //The HMAC-SHA256 hash is specified in [FIPS180-2] and [RFC2104].

                    HMACSHA256 hmacSha = new HMACSHA256(cryptoInfo.SigningKey);
                    computedSignature = hmacSha.ComputeHash(bytesToCompute);
                }

                //[MS-SMB2] 3.1.5.1
                //If the first 16 bytes (the high-order portion) of the computed signature from step 3 or step 4 matches the saved signature from step 1, the message is signed correctly
                // compare the first 16 bytes of the originalSignature and computedSignature
                return(packet.Header.Signature.SequenceEqual(computedSignature.Take(Smb2Consts.SignatureSize)));
            }
            catch (Exception ex)
            {
                throw new Exception("Error happened during signature verification of packet: " + packet.ToString() + ". Exception message: " + ex.Message);
            }
        }