From patchwork Wed Jan 26 05:28:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 2257 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director14.mail.ord1d.rsapps.net ([172.30.191.6]) by backend41.mail.ord1d.rsapps.net with LMTP id 8PjJFed28WE6NAAAqwncew (envelope-from ) for ; Wed, 26 Jan 2022 11:29:27 -0500 Received: from proxy10.mail.ord1d.rsapps.net ([172.30.191.6]) by director14.mail.ord1d.rsapps.net with LMTP id 2PrVGud28WEeewAAeJ7fFg (envelope-from ) for ; Wed, 26 Jan 2022 11:29:27 -0500 Received: from smtp17.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy10.mail.ord1d.rsapps.net with LMTPS id kJl/Gud28WHvWwAAfSg8FQ (envelope-from ) for ; Wed, 26 Jan 2022 11:29:27 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp17.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 207b8994-7ec5-11ec-9891-5254008de1cb-1-1 Received: from [216.105.38.7] ([216.105.38.7:49860] helo=lists.sourceforge.net) by smtp17.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 2B/B9-17316-6E671F16; Wed, 26 Jan 2022 11:29:26 -0500 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.94.2) (envelope-from ) id 1nCl9q-0004lk-2E; Wed, 26 Jan 2022 16:28:28 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nCl9m-0004lc-Pt for openvpn-devel@lists.sourceforge.net; Wed, 26 Jan 2022 16:28:25 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=SYZIiJwnxLNMJL6+oZIsfBGsWh2bgZQbNShCv+9xWNg=; b=KUaxE3+0+tvIVpXe2RuSGlWEVx YljNDWi2JibJarBxqT+WEHpxTIZXqKbZtPLGvq0GYs2IMX5fwvNcssDPkCXQk55gDIoru82sq6g96 07C1ROcvo6OmHhy8JCRleT2uyFXUX9yktWeEx5+OJQnqqhUEXbJ635280jIVgZzyjDQ0=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject:Cc:To:From :Sender:Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=SYZIiJwnxLNMJL6+oZIsfBGsWh2bgZQbNShCv+9xWNg=; b=K INfxaTcec9K0yTH2ROCOU3LNBb6XnGSyRUbKT/WuF6CGTWr6ubhiHJwMNpsmY2pf1KdrGk0g6+fq3 1yl+O9bqrCiIw0AlkCJ6S48r+1rok99snTMRHDN7A7NL/xLbpNRo6FrfXN2r1LbWjm/LVa3J0iIQp kLspPkmCO86k3/PM=; Received: from s2.neomailbox.net ([5.148.176.60]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) id 1nCl9j-00040b-DS for openvpn-devel@lists.sourceforge.net; Wed, 26 Jan 2022 16:28:25 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 26 Jan 2022 17:28:29 +0100 Message-Id: <20220126162830.20952-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: With cipher validation performed in cipher_get(), a cipher is never returned in any case if some check fails. This prevents OpenVPN from operating on all ciphers provided by the SSL library, like printing them to the user. Content analysis details: (0.0 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-Headers-End: 1nCl9j-00040b-DS Subject: [Openvpn-devel] [PATCH 1/2] crypto: move validation logic from cipher_get to cipher_valid X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox With cipher validation performed in cipher_get(), a cipher is never returned in any case if some check fails. This prevents OpenVPN from operating on all ciphers provided by the SSL library, like printing them to the user. Move the validation logic to cipher_valid() so that checks are performed only when OpenVPN really want to know if a cipher is usable or not. Fixes: ce2954a0 ("Remove cipher_kt_t and change type to const char* in API") Cc: Arne Schwabe Signed-off-by: Antonio Quartulli --- NOTE: mbedtls already follows this approach and did not require any change. src/openvpn/crypto_openssl.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index a725306c..ea0147db 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -565,16 +565,19 @@ rand_bytes(uint8_t *output, int len) static evp_cipher_type * cipher_get(const char *ciphername) { - evp_cipher_type *cipher = NULL; - ASSERT(ciphername); ciphername = translate_cipher_name_from_openvpn(ciphername); - cipher = EVP_CIPHER_fetch(NULL, ciphername, NULL); + return EVP_CIPHER_fetch(NULL, ciphername, NULL); +} - if (NULL == cipher) +bool cipher_valid(const char *ciphername) +{ + evp_cipher_type *cipher = cipher_get(ciphername); + if (!cipher) { - return NULL; + crypto_msg(D_LOW, "Cipher algorithm '%s' not found", ciphername); + return false; } #ifdef OPENSSL_FIPS @@ -585,7 +588,7 @@ cipher_get(const char *ciphername) { msg(D_LOW, "Cipher algorithm '%s' is known by OpenSSL library but " "currently disabled by running in FIPS mode.", ciphername); - return NULL; + return false; } #endif if (EVP_CIPHER_key_length(cipher) > MAX_CIPHER_KEY_LENGTH) @@ -594,22 +597,11 @@ cipher_get(const char *ciphername) "which is larger than " PACKAGE_NAME "'s current maximum key size " "(%d bytes)", ciphername, EVP_CIPHER_key_length(cipher), MAX_CIPHER_KEY_LENGTH); - return NULL; + return false; } - return cipher; -} - -bool cipher_valid(const char *ciphername) -{ - evp_cipher_type *cipher = cipher_get(ciphername); - bool valid = (cipher != NULL); - if (!valid) - { - crypto_msg(D_LOW, "Cipher algorithm '%s' not found", ciphername); - } EVP_CIPHER_free(cipher); - return valid; + return true; } bool cipher_var_key_size(const char *ciphername) From patchwork Wed Jan 26 05:28:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 2258 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.30.191.6]) by backend41.mail.ord1d.rsapps.net with LMTP id EBqqFud28WF2NAAAqwncew (envelope-from ) for ; Wed, 26 Jan 2022 11:29:27 -0500 Received: from proxy2.mail.ord1d.rsapps.net ([172.30.191.6]) by director9.mail.ord1d.rsapps.net with LMTP id mHIlG+d28WG2SAAAalYnBA (envelope-from ) for ; Wed, 26 Jan 2022 11:29:27 -0500 Received: from smtp39.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy2.mail.ord1d.rsapps.net with LMTPS id QDDtGud28WHHTgAAfawv4w (envelope-from ) for ; Wed, 26 Jan 2022 11:29:27 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp39.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 20514d6e-7ec5-11ec-b599-525400a97bbc-1-1 Received: from [216.105.38.7] ([216.105.38.7:39760] helo=lists.sourceforge.net) by smtp39.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 0E/D0-11697-6E671F16; Wed, 26 Jan 2022 11:29:26 -0500 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.94.2) (envelope-from ) id 1nCl9r-0002Qv-3w; Wed, 26 Jan 2022 16:28:29 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nCl9o-0002Qp-TT for openvpn-devel@lists.sourceforge.net; Wed, 26 Jan 2022 16:28:27 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=5LqB91++BPrKLv+34QfoXwYESIvbSjWJp6L+dW6Tb2U=; b=ZLEQQQD1gamn0kDclR5SvhK1fO z0Wui/pCYsqMZSzZXRZ6I10yO/J0CZZi159JO1ROW0a0KyjOSJ8EHE3xmZKKHL3J4eSqFdfz2m0vB lpETORm+FMQuD4MyO/iddzaCKG8mF+laXPGdZVXjW5t/J416+N6gvlgltiZkQgUYWcV8=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=5LqB91++BPrKLv+34QfoXwYESIvbSjWJp6L+dW6Tb2U=; b=SaVhAKwakCsJTNIkwwfDUNcRDE 2PidhAOot6uy04+uqZp9XJzM/RHcg0saHMv0Bn4d0GsG3N88PHbHGmoVdb58zfHPh/KIjc6s4M319 Y+SorOT1HGt56e2xg5oAE8/Hy2KZKKl5rGhC1PpDgSTI9IetUIwgKPQV7pTSAxpF21iU=; Received: from s2.neomailbox.net ([5.148.176.60]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) id 1nCl9m-00EfSX-Pr for openvpn-devel@lists.sourceforge.net; Wed, 26 Jan 2022 16:28:27 +0000 From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Wed, 26 Jan 2022 17:28:30 +0100 Message-Id: <20220126162830.20952-2-a@unstable.cc> In-Reply-To: <20220126162830.20952-1-a@unstable.cc> References: <20220126162830.20952-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Our crypto API already provides a function performing a validity check on the specified ciphername. The OpenSSL counterpart also checks for the cipher being FIPS-enabled. This API is cipher_valid(). Extend it so that it can provide a reason whenever the cipher is not valid and use it in crypto.c. Content analysis details: (0.0 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-Headers-End: 1nCl9m-00EfSX-Pr Subject: [Openvpn-devel] [PATCH 2/2] crypto: move OpenSSL specific FIPS check to its backend X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Sommerseth , Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Our crypto API already provides a function performing a validity check on the specified ciphername. The OpenSSL counterpart also checks for the cipher being FIPS-enabled. This API is cipher_valid(). Extend it so that it can provide a reason whenever the cipher is not valid and use it in crypto.c. This way we move any OpenSSL specific bit to its own backend and directly use the new cipher_valid_reason() API in the generic code. This patch fixes compilations with mbedTLS when some OpenSSL is also installed. The issue was introduced with: 544330fe ("crypto: Fix OPENSSL_FIPS enabled builds") Cc: David Sommerseth Signed-off-by: Antonio Quartulli --- NOTE: This patch makes "crypto.c: remove (dead) OpenSSL specific code" obsolete. Compiled with varoius libraries: * Testing OpenSSL-1.0.2... * OpenSSL-1.0.2 OK * Testing OpenSSL-1.1.0... * OpenSSL-1.1.0 OK * Testing OpenSSL-1.1.1... * OpenSSL-1.1.1 OK * Testing OpenSSL-3.0.1... * OpenSSL-3.0.1 OK * Testing mbedtls-2.7.19... * mbedtls-2.7.19 OK * Testing mbedtls-2.10.0... * mbedtls-2.10.0 OK * Testing mbedtls-2.14.1... * mbedtls-2.14.1 OK * Testing mbedtls-2.16.11... * mbedtls-2.16.11 OK * Testing mbedtls-2.20.0... * mbedtls-2.20.0 OK * Testing mbedtls-2.26.0... * mbedtls-2.26.0 OK * Testing mbedtls-2.27.0... * mbedtls-2.27.0 OK src/openvpn/crypto.c | 11 +++-------- src/openvpn/crypto_backend.h | 22 +++++++++++++++++++++- src/openvpn/crypto_mbedtls.c | 13 +++++++++---- src/openvpn/crypto_openssl.c | 8 ++++++-- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 0aa76e05..b1303061 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -34,7 +34,6 @@ #include "error.h" #include "integer.h" #include "platform.h" -#include "openssl_compat.h" #include "memdbg.h" @@ -1704,16 +1703,12 @@ print_cipher(const char *ciphername) { printf(", TLS client/server mode only"); } -#ifdef OPENSSL_FIPS - evp_cipher_type *cipher = EVP_CIPHER_fetch(NULL, ciphername, NULL); - if (FIPS_mode() && cipher - && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_FIPS)) + const char *reason; + if (!cipher_valid_reason(ciphername, &reason)) { - printf(", disabled by FIPS mode"); + printf(", %s", reason); } - EVP_CIPHER_free(cipher); -#endif printf(")\n"); } diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h index 7beaf9c3..e447036d 100644 --- a/src/openvpn/crypto_backend.h +++ b/src/openvpn/crypto_backend.h @@ -187,6 +187,21 @@ void cipher_des_encrypt_ecb(const unsigned char key[DES_KEY_LENGTH], */ #define MAX_CIPHER_KEY_LENGTH 64 +/** + * Returns if the cipher is valid, based on the given cipher name and provides a + * reason if invalid. + * + * @param ciphername Name of the cipher to check for validity (e.g. + * \c AES-128-CBC). Will be translated to the library name + * from the openvpn config name if needed. + * @param reason Pointer where a static string indicating the reason + * for rejecting the cipher should be stored. It is set to + * NULL if the cipher is valid. + * + * @return if the cipher is valid + */ +bool cipher_valid_reason(const char *ciphername, const char **reason); + /** * Returns if the cipher is valid, based on the given cipher name. * @@ -196,7 +211,12 @@ void cipher_des_encrypt_ecb(const unsigned char key[DES_KEY_LENGTH], * * @return if the cipher is valid */ -bool cipher_valid(const char *ciphername); +static inline bool cipher_valid(const char *ciphername) +{ + const char *reason; + return cipher_valid_reason(ciphername, &reason); +} + /** * Checks if the cipher is defined and is not the null (none) cipher diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index 01bfa020..a771777e 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -403,14 +403,17 @@ cipher_get(const char* ciphername) } bool -cipher_valid(const char *ciphername) +cipher_valid_reason(const char *ciphername, const char **reason) { + ASSERT(reason); + const mbedtls_cipher_info_t *cipher = cipher_get(ciphername); if (NULL == cipher) { msg(D_LOW, "Cipher algorithm '%s' not found", ciphername); - return NULL; + *reason = "disabled because unknown"; + return false; } if (cipher->key_bitlen/8 > MAX_CIPHER_KEY_LENGTH) @@ -418,10 +421,12 @@ cipher_valid(const char *ciphername) msg(D_LOW, "Cipher algorithm '%s' uses a default key size (%d bytes) " "which is larger than " PACKAGE_NAME "'s current maximum key size " "(%d bytes)", ciphername, cipher->key_bitlen/8, MAX_CIPHER_KEY_LENGTH); - return NULL; + *reason = "disabled due to key size too large"; + return false; } - return cipher != NULL; + *reason = NULL; + return true; } const char * diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index ea0147db..79afa4ab 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -571,12 +571,13 @@ cipher_get(const char *ciphername) return EVP_CIPHER_fetch(NULL, ciphername, NULL); } -bool cipher_valid(const char *ciphername) +bool cipher_valid_reason(const char *ciphername, const char **reason) { evp_cipher_type *cipher = cipher_get(ciphername); if (!cipher) { crypto_msg(D_LOW, "Cipher algorithm '%s' not found", ciphername); + *reason = "disabled because unknown"; return false; } @@ -588,6 +589,7 @@ bool cipher_valid(const char *ciphername) { msg(D_LOW, "Cipher algorithm '%s' is known by OpenSSL library but " "currently disabled by running in FIPS mode.", ciphername); + *reason = "disabled by FIPS mode"; return false; } #endif @@ -597,11 +599,13 @@ bool cipher_valid(const char *ciphername) "which is larger than " PACKAGE_NAME "'s current maximum key size " "(%d bytes)", ciphername, EVP_CIPHER_key_length(cipher), MAX_CIPHER_KEY_LENGTH); + *reason = "disabled due to key size too large"; return false; } + *reason = NULL; EVP_CIPHER_free(cipher); - return true; + return cipher; } bool cipher_var_key_size(const char *ciphername)