public static byte[] Decrypt(byte[] bytes, Dictionary <ulong, Smb2CryptoInfo> cryptoInfoTable, Smb2Role role) { // Client: If the size of the message received from the server is not greater than the size of SMB2 TRANSFORM_HEADER as specified, the client MUST discard the message. // Server: If the size of the message received from the client is not greater than the size of the SMB2 TRANSFORM_HEADER, the server MUST disconnect the connection. int minimumLength = Marshal.SizeOf(typeof(Transform_Header)); if (bytes.Length < minimumLength) { throw new InvalidOperationException( String.Format( "Too less data for encrypted message. Expected length more than {0}, actual {1}.", minimumLength, bytes.Length ) ); } Transform_Header transformHeader = Smb2Utility.UnmarshalStructure <Transform_Header>(bytes); // Client: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the client MUST discard the message. // Server: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the server MUST disconnect the connection. if (transformHeader.Flags != TransformHeaderFlags.Encrypted) { throw new InvalidOperationException( String.Format( "Flags/EncryptionAlgorithm field is invalid for encrypted message. Expected value 0x0001, actual {0}.", (ushort)transformHeader.Flags ) ); } if (transformHeader.SessionId == 0 || !cryptoInfoTable.ContainsKey(transformHeader.SessionId)) { throw new InvalidOperationException("Invalid SessionId in TRANSFORM_HEADER."); } Smb2CryptoInfo cryptoInfo = cryptoInfoTable[transformHeader.SessionId]; using (var bcrypt = new BCryptAlgorithm("AES")) { int nonceLength = 0; BCryptCipherMode mode = BCryptCipherMode.NotAvailable; GetCryptoParams(cryptoInfo, CryptoOperationType.Decrypt, out mode, out nonceLength); bcrypt.Mode = mode; bcrypt.Key = role == Smb2Role.Server ? cryptoInfo.ServerInKey : cryptoInfo.ServerOutKey; return(bcrypt.Decrypt(bytes.Skip(52).ToArray(), transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), bytes.Skip(20).Take(32).ToArray(), transformHeader.Signature)); } }
public static byte[] Decrypt(byte[] bytes, Dictionary <ulong, Smb2CryptoInfo> cryptoInfoTable, Smb2Role role, out Transform_Header transformHeader) { var encryptedPacket = new Smb2EncryptedPacket(); int consumedLen; int expectedLen; encryptedPacket.FromBytes(bytes, out consumedLen, out expectedLen); transformHeader = encryptedPacket.Header; // For client: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the client MUST discard the message. // For server: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the server MUST disconnect the connection. if (transformHeader.Flags != TransformHeaderFlags.Encrypted) { throw new InvalidOperationException( String.Format( "Flags/EncryptionAlgorithm field is invalid for encrypted message. Expected value 0x0001, actual {0}.", (ushort)transformHeader.Flags ) ); } if (transformHeader.SessionId == 0 || !cryptoInfoTable.ContainsKey(transformHeader.SessionId)) { throw new InvalidOperationException("Invalid SessionId in TRANSFORM_HEADER."); } Smb2CryptoInfo cryptoInfo = cryptoInfoTable[transformHeader.SessionId]; using (var bcrypt = new BCryptAlgorithm("AES")) { int nonceLength = 0; BCryptCipherMode mode = BCryptCipherMode.NotAvailable; GetCryptoParams(cryptoInfo, CryptoOperationType.Decrypt, out mode, out nonceLength); bcrypt.Mode = mode; bcrypt.Key = role == Smb2Role.Server ? cryptoInfo.ServerInKey : cryptoInfo.ServerOutKey; // Auth data is Transform_Header start from Nonce, excluding ProtocolId and Signature. var authData = Smb2Utility.MarshalStructure(transformHeader).Skip((int)Marshal.OffsetOf <Transform_Header>("Nonce")).ToArray(); return(bcrypt.Decrypt(encryptedPacket.EncryptdData, transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), authData, transformHeader.Signature)); } }
public static byte[] Decrypt(byte[] bytes, Dictionary <ulong, Smb2CryptoInfo> cryptoInfoTable, Smb2Role role) { Transform_Header transformHeader = Smb2Utility.UnmarshalStructure <Transform_Header>(bytes); if (transformHeader.SessionId == 0 || !cryptoInfoTable.ContainsKey(transformHeader.SessionId)) { throw new InvalidOperationException("Invalid SessionId in TRANSFORM_HEADER."); } Smb2CryptoInfo cryptoInfo = cryptoInfoTable[transformHeader.SessionId]; using (var bcrypt = new BCryptAlgorithm("AES")) { int nonceLength = 0; BCryptCipherMode mode = BCryptCipherMode.NotAvailable; GetCryptoParams(cryptoInfo, CryptoOperationType.Decrypt, out mode, out nonceLength); bcrypt.Mode = mode; bcrypt.Key = role == Smb2Role.Server ? cryptoInfo.ServerInKey : cryptoInfo.ServerOutKey; return(bcrypt.Decrypt(bytes.Skip(52).ToArray(), transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), bytes.Skip(20).Take(32).ToArray(), transformHeader.Signature)); } }