From 56b0402e945360eaa2ad64922a6591f7ccea9ee5 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Mon, 25 May 2026 11:49:12 +0200 Subject: [PATCH] [core,connection] disable RDP Security in FIPS mode The FIPS mode block in `rdp_client_connect` forces `ENCRYPTION_METHOD_FIPS` which uses 3DES-EDE3-CBC for the RDP Security layer encryption. Starting with OpenSSL 3.4, the FIPS provider marks Triple-DES as a non-approved algorithm (`fips=no`) and rejects its use by default. This causes connection failures when RDP Security negotiation is attempted in FIPS mode on systems with OpenSSL 3.4 or newer. This commit addresses that by disabling `RdpSecurity` entirely when 3DES-EDE3-CBC is not available, so that only NLA/TLS (which use FIPS-approved AES) are negotiated. On older OpenSSL versions, the existing `ENCRYPTION_METHOD_FIPS` behavior is preserved since 3DES still works there. Made-with: Cursor --- libfreerdp/core/connection.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index c013e9b38..0d72c0e50 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -325,15 +325,31 @@ BOOL rdp_client_connect(rdpRdp* rdp) /* FIPS Mode forces the following and overrides the following(by happening later * in the command line processing): * 1. Forces the only supported RDP encryption method to be FIPS. - * 2. Disables NTLM authentication (not FIPS compliant due to MD4/RC4). */ + * 2. Disables NTLM authentication (not FIPS compliant due to MD4/RC4). + * 3. Disables RDP Security if 3DES is not available in the crypto provider. */ if (settings->FIPSMode || winpr_FIPSMode()) { + settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; + if (!settings->AuthenticationPackageList) { if (!freerdp_settings_set_string(settings, FreeRDP_AuthenticationPackageList, "!ntlm")) return FALSE; } + + const BYTE key[WINPR_CIPHER_MAX_KEY_LENGTH] = WINPR_C_ARRAY_INIT; + const BYTE iv[WINPR_CIPHER_MAX_IV_LENGTH] = WINPR_C_ARRAY_INIT; + WINPR_CIPHER_CTX* ctx = winpr_Cipher_NewEx(WINPR_CIPHER_DES_EDE3_CBC, WINPR_ENCRYPT, key, + sizeof(key), iv, sizeof(iv)); + if (ctx) + { + winpr_Cipher_Free(ctx); + } + else + { + settings->RdpSecurity = FALSE; + } } UINT32 TcpConnectTimeout = freerdp_settings_get_uint32(settings, FreeRDP_TcpConnectTimeout); -- 2.54.0