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)