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)); } }
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>(); } }
/// <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); } }