From patchwork Mon Sep 7 06:22:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 1418 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.27.255.50]) by backend30.mail.ord1d.rsapps.net with LMTP id GIMmKn5eVl+bCwAAIUCqbw (envelope-from ) for ; Mon, 07 Sep 2020 12:23:26 -0400 Received: from proxy15.mail.iad3a.rsapps.net ([172.27.255.50]) by director9.mail.ord1d.rsapps.net with LMTP id yMf6KX5eVl+RegAAalYnBA (envelope-from ) for ; Mon, 07 Sep 2020 12:23:26 -0400 Received: from smtp50.gate.iad3a ([172.27.255.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy15.mail.iad3a.rsapps.net with LMTPS id qHBqIn5eVl9TGQAAHi9b9g (envelope-from ) for ; Mon, 07 Sep 2020 12:23:26 -0400 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: smtp50.gate.iad3a.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=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: 746905e6-f126-11ea-80bc-525400c2fb51-1-1 Received: from [216.105.38.7] ([216.105.38.7:50736] helo=lists.sourceforge.net) by smtp50.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id A1/F2-03190-D7E565F5; Mon, 07 Sep 2020 12:23:26 -0400 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.90_1) (envelope-from ) id 1kFJuh-0005vF-1B; Mon, 07 Sep 2020 16:22:39 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kFJue-0005uf-NN for openvpn-devel@lists.sourceforge.net; Mon, 07 Sep 2020 16:22:36 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:To: From:Sender:Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding: 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=L1a/KL/5l1DaUniZrdlTZr28AWKd1KpYa1iAwU6t7xQ=; b=Q2KCW20jNklwJ5y0GJ65AmlZ7I HdYwCBmXT91FXoDL2mxA6i+ifvtve59xbD4MlCiosdtxiTuEasUYzSaZUf1kVKydu/uUT7TZQRbZR KTWiUwGpCHaHfEe4trL+WrMFddWbqfahyyFNiHGzc/dQy8hvBL+d1D/WwcKjnCXBNPjQ=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc :MIME-Version:Content-Type:Content-Transfer-Encoding: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=L1a/KL/5l1DaUniZrdlTZr28AWKd1KpYa1iAwU6t7xQ=; b=AnROg+XI7+8UymwjPDZV8J3gKs sYeU3mvLsIyQEiIIKu0EheedfldR8gPzwu3WJnye3EU1qZ0weDBOKdaomY08eoZuv7/Lht4GGbfch TdDE0hp+PnFXsyYHEP4fUoruADhIiLcYir/5XBhYkH6Cf+X5MiZS6jewxx6hSB65xubQ=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1kFJub-00FgaT-Qx for openvpn-devel@lists.sourceforge.net; Mon, 07 Sep 2020 16:22:36 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.94 (FreeBSD)) (envelope-from ) id 1kFJuP-000Nb9-CG for openvpn-devel@lists.sourceforge.net; Mon, 07 Sep 2020 18:22:21 +0200 Received: (nullmailer pid 20975 invoked by uid 10006); Mon, 07 Sep 2020 16:22:21 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Mon, 7 Sep 2020 18:22:19 +0200 Message-Id: <20200907162221.20928-1-arne@rfc2549.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200825073643.15920-2-arne@rfc2549.org> References: <20200825073643.15920-2-arne@rfc2549.org> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-Headers-End: 1kFJub-00FgaT-Qx Subject: [Openvpn-devel] [PATCH 3/5] Allow running a default configuration with TLS libraries without BF-CBC 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: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Modern TLS libraries might drop Blowfish by default or distributions might disable Blowfish in OpenSSL/mbed TLS. We still signal OCC options with BF-CBC compatible strings. To avoid requiring BF-CBC for this, special case this one usage of BF-CBC enough to avoid a hard requirement on Blowfish in the default configuration. Signed-off-by: Arne Schwabe --- src/openvpn/init.c | 18 +++++++++------ src/openvpn/options.c | 51 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index dff090b1..1e0baf2a 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2752,14 +2752,18 @@ do_init_crypto_tls_c1(struct context *c) #endif /* if P2MP */ } - /* Do not warn if we only have BF-CBC in options->ciphername - * because it is still the default cipher */ - bool warn = !streq(options->ciphername, "BF-CBC") - || options->enable_ncp_fallback; - /* Get cipher & hash algorithms */ - init_key_type(&c->c1.ks.key_type, options->ciphername, options->authname, - options->keysize, true, warn); + if (!options->ncp_enabled || options->enable_ncp_fallback + || !streq(options->ciphername, "BF-CBC")) + { + /* Get cipher & hash algorithms + * skip BF-CBC for NCP setups when cipher as this is the default + * and is also special cased later to allow it to be not available + * as we need to construct a fake BF-CBC occ string + */ + init_key_type(&c->c1.ks.key_type, options->ciphername, options->authname, + options->keysize, true, true); + } /* Initialize PRNG with config-specified digest */ prng_init(options->prng_hash, options->prng_nonce_secret_len); diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 90e78a7b..01da88ad 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -3640,11 +3640,32 @@ calc_options_string_link_mtu(const struct options *o, const struct frame *frame) { struct frame fake_frame = *frame; struct key_type fake_kt; - init_key_type(&fake_kt, o->ciphername, o->authname, o->keysize, true, - false); + frame_remove_from_extra_frame(&fake_frame, crypto_max_overhead()); - crypto_adjust_frame_parameters(&fake_frame, &fake_kt, o->replay, - cipher_kt_mode_ofb_cfb(fake_kt.cipher)); + + /* o->ciphername can be still BF-CBC and our SSL library might not like + * like it, workaround this important corner case in the name of + * compatibility and not stopping openvpn on our default configuration + */ + if ((strcmp(o->ciphername, "BF-CBC") == 0) + && cipher_kt_get(o->ciphername) == NULL) + { + init_key_type(&fake_kt, "none", o->authname, o->keysize, true, + false); + + crypto_adjust_frame_parameters(&fake_frame, &fake_kt, o->replay, + cipher_kt_mode_ofb_cfb(fake_kt.cipher)); + /* 64 bit block size, 64 bit IV size */ + frame_add_to_extra_frame(&fake_frame, 64/8 + 64/8); + } + else + { + init_key_type(&fake_kt, o->ciphername, o->authname, o->keysize, true, + false); + + crypto_adjust_frame_parameters(&fake_frame, &fake_kt, o->replay, + cipher_kt_mode_ofb_cfb(fake_kt.cipher)); + } frame_finalize(&fake_frame, o->ce.link_mtu_defined, o->ce.link_mtu, o->ce.tun_mtu_defined, o->ce.tun_mtu); msg(D_MTU_DEBUG, "%s: link-mtu %u -> %d", __func__, (unsigned int) link_mtu, @@ -3812,18 +3833,32 @@ options_string(const struct options *o, + (TLS_SERVER == true) <= 1); - init_key_type(&kt, o->ciphername, o->authname, o->keysize, true, - false); + /* Skip resolving BF-CBC to allow SSL libraries without BF-CBC + * to work here in the default configuration */ + const char *ciphername = o->ciphername; + int keysize; + + if (strcmp(o->ciphername, "BF-CBC") == 0) { + init_key_type(&kt, "none", o->authname, o->keysize, true, + false); + ciphername = cipher_kt_name(kt.cipher); + keysize = 128; + } + else + { + init_key_type(&kt, o->ciphername, o->authname, o->keysize, true, + false); + keysize = kt.cipher_length * 8; + } /* Only announce the cipher to our peer if we are willing to * support it */ - const char *ciphername = cipher_kt_name(kt.cipher); if (p2p_nopull || !o->ncp_enabled || tls_item_in_cipher_list(ciphername, o->ncp_ciphers)) { buf_printf(&out, ",cipher %s", ciphername); } buf_printf(&out, ",auth %s", md_kt_name(kt.digest)); - buf_printf(&out, ",keysize %d", kt.cipher_length * 8); + buf_printf(&out, ",keysize %d", keysize); if (o->shared_secret_file) { buf_printf(&out, ",secret"); From patchwork Mon Sep 7 06:22:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 1417 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director10.mail.ord1d.rsapps.net ([172.27.255.50]) by backend30.mail.ord1d.rsapps.net with LMTP id uGifF3leVl+QagAAIUCqbw (envelope-from ) for ; Mon, 07 Sep 2020 12:23:21 -0400 Received: from proxy3.mail.iad3a.rsapps.net ([172.27.255.50]) by director10.mail.ord1d.rsapps.net with LMTP id uMplF3leVl8wDAAApN4f7A (envelope-from ) for ; Mon, 07 Sep 2020 12:23:21 -0400 Received: from smtp37.gate.iad3a ([172.27.255.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy3.mail.iad3a.rsapps.net with LMTPS id wKx4EHleVl+1IgAAYaqY3Q (envelope-from ) for ; Mon, 07 Sep 2020 12:23:21 -0400 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: smtp37.gate.iad3a.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=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: 71326b7e-f126-11ea-ad2d-525400dc5f6a-1-1 Received: from [216.105.38.7] ([216.105.38.7:48930] helo=lists.sourceforge.net) by smtp37.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 9D/7F-14040-87E565F5; Mon, 07 Sep 2020 12:23:20 -0400 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.90_1) (envelope-from ) id 1kFJud-0000Y9-H0; Mon, 07 Sep 2020 16:22:35 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kFJub-0000Xy-Hi for openvpn-devel@lists.sourceforge.net; Mon, 07 Sep 2020 16:22:33 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:To: From:Sender:Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding: 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=958mO5fhZflXi5nn3JH5xK07MahKLGaaBLShSWOfGQI=; b=aSfTejmPElRiKLqiGPzJpZeOU7 u2KLGCCk4jitzwB4NFlvPJkrDRq/eVoLrX1P4odhKwPHvq8nANEAsTOg+xJiSC7r73+jzNMqbItYV 6DbsSfo0TO/fnOaoob+ktFALXtxSB+8cQbGhNFHPbEY3RNF1ddO7Kta5iQHvEVedVsk4=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc :MIME-Version:Content-Type:Content-Transfer-Encoding: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=958mO5fhZflXi5nn3JH5xK07MahKLGaaBLShSWOfGQI=; b=mtdYKdx7TFd/OItP4hlZZGSOEo Mk2KkNpW1Raxxv+sruBBJhv2zoFRRz8vRzsS7Iw6DsKun5TarfZ/12wyu4gOa0aGNtNCnpSj0l+DJ ZN938bVt/XJu1KAmaXLbED/ta1dWXS04P+GtentgnqQen5Po3jL882Q6PSAh7fOXQ3Us=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1kFJuW-00Fxg8-KI for openvpn-devel@lists.sourceforge.net; Mon, 07 Sep 2020 16:22:33 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.94 (FreeBSD)) (envelope-from ) id 1kFJuP-000NbC-Ec for openvpn-devel@lists.sourceforge.net; Mon, 07 Sep 2020 18:22:21 +0200 Received: (nullmailer pid 20978 invoked by uid 10006); Mon, 07 Sep 2020 16:22:21 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Mon, 7 Sep 2020 18:22:20 +0200 Message-Id: <20200907162221.20928-2-arne@rfc2549.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200907162221.20928-1-arne@rfc2549.org> References: <20200825073643.15920-2-arne@rfc2549.org> <20200907162221.20928-1-arne@rfc2549.org> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-Headers-End: 1kFJuW-00Fxg8-KI Subject: [Openvpn-devel] [PATCH 4/5] Check return values in md_ctx_init and hmac_ctx_init 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: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Without this OpenVPN will later segfault on a FIPS enabled system due to the algorithm available but not allowed. Signed-off-by: Arne Schwabe --- src/openvpn/crypto_openssl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index c60d4a54..75557cca 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -954,7 +954,10 @@ md_ctx_init(EVP_MD_CTX *ctx, const EVP_MD *kt) ASSERT(NULL != ctx && NULL != kt); EVP_MD_CTX_init(ctx); - EVP_DigestInit(ctx, kt); + if (EVP_DigestInit(ctx, kt) != 1) + { + crypto_msg(M_FATAL, "EVP_DigestInit failed"); + } } void @@ -1011,7 +1014,10 @@ hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len, ASSERT(NULL != kt && NULL != ctx); HMAC_CTX_reset(ctx); - HMAC_Init_ex(ctx, key, key_len, kt, NULL); + if (HMAC_Init_ex(ctx, key, key_len, kt, NULL) != 1) + { + crypto_msg(M_FATAL, "HMAC_Init_ex failed"); + } /* make sure we used a big enough key */ ASSERT(HMAC_size(ctx) <= key_len); From patchwork Mon Sep 7 06:22:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 1419 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director12.mail.ord1d.rsapps.net ([172.27.255.53]) by backend30.mail.ord1d.rsapps.net with LMTP id SNSlAYheVl+bCwAAIUCqbw (envelope-from ) for ; Mon, 07 Sep 2020 12:23:36 -0400 Received: from proxy13.mail.iad3a.rsapps.net ([172.27.255.53]) by director12.mail.ord1d.rsapps.net with LMTP id 0DyDAYheVl8WCgAAIasKDg (envelope-from ) for ; Mon, 07 Sep 2020 12:23:36 -0400 Received: from smtp34.gate.iad3a ([172.27.255.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy13.mail.iad3a.rsapps.net with LMTPS id MIXXNodeVl+WaQAAwhxzoA (envelope-from ) for ; Mon, 07 Sep 2020 12:23:35 -0400 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: smtp34.gate.iad3a.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=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: 79f6e0be-f126-11ea-a209-525400865cc7-1-1 Received: from [216.105.38.7] ([216.105.38.7:57290] helo=lists.sourceforge.net) by smtp34.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 70/6B-01277-78E565F5; Mon, 07 Sep 2020 12:23:35 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1kFJuo-00011Y-PY; Mon, 07 Sep 2020 16:22:46 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kFJui-00011I-5j for openvpn-devel@lists.sourceforge.net; Mon, 07 Sep 2020 16:22:40 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:To: From:Sender:Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding: 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=/ElJuhPgnbB8wPAkuanrl31x44nvP/ymU+GXO0tOfkg=; b=RgluM6LovB+EycG6jY60Wf87Wm cewHhkIzsvYkisGcRFeibcpaNEdTbEY527URDIF73F3j+HdzUhkkro3ZFSa9mdBjmCFteYmEnBezV AF4lc4A3JATcBbKivyNAIMlXkDtDPW7nTbYPNZ+f717/qe4V1JEaDToYktZLiQnZ/gLs=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc :MIME-Version:Content-Type:Content-Transfer-Encoding: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=/ElJuhPgnbB8wPAkuanrl31x44nvP/ymU+GXO0tOfkg=; b=X87PRGc8cdi5AV55pw83OFazRQ fINxrVLheHZdNBGwrSG8gaPEHNSW/zSsaVpT+nIQATW3msfBmq0WHYn3OH+Rg7RQGmmE/16YqB4ai fnHTMMqpXQ4dfhmm7qOcukpIY9t+VJFGMtiBvpKNvsRcgdhnMsJQcZV6KhXXnIs7tGzI=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1kFJud-00FxgO-6O for openvpn-devel@lists.sourceforge.net; Mon, 07 Sep 2020 16:22:40 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.94 (FreeBSD)) (envelope-from ) id 1kFJuP-000NbF-Gn for openvpn-devel@lists.sourceforge.net; Mon, 07 Sep 2020 18:22:21 +0200 Received: (nullmailer pid 20981 invoked by uid 10006); Mon, 07 Sep 2020 16:22:21 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Mon, 7 Sep 2020 18:22:21 +0200 Message-Id: <20200907162221.20928-3-arne@rfc2549.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200907162221.20928-1-arne@rfc2549.org> References: <20200825073643.15920-2-arne@rfc2549.org> <20200907162221.20928-1-arne@rfc2549.org> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-Headers-End: 1kFJud-00FxgO-6O Subject: [Openvpn-devel] [PATCH 5/5] Prefer TLS libraries TLS PRF function, fix OpenVPN in FIPS mode 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: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox This moves from using our own copy of the TLS1 PRF function to using TLS library provided function where possible. This includes currently OpenSSL 1.1.0+ and mbed TLS 2.18+. For the libraries where it is not possible to use the library's own function, we still use our own implementation. mbed TLS will continue to use our own old PRF function while for OpenSSL we will use a adapted version from OpenSSL 1.0.2t code. The version allows to be used in a FIPS enabled environment. The old OpenSSL and mbed TLS implementation could have shared some more code but as we will eventually drop support for older TLS libraries, the separation makes it easier it remove that code invdidually. No FIPS conformitiy testing etc has been done, this is only about allowing OpenVPN on a system where FIPS mode has been enabled system wide (e.g. on RHEL derivates). Signed-off-by: Arne Schwabe --- src/openvpn/crypto_backend.h | 19 +++ src/openvpn/crypto_mbedtls.c | 143 ++++++++++++++++++++ src/openvpn/crypto_openssl.c | 172 ++++++++++++++++++++++++- src/openvpn/ssl.c | 130 +------------------ tests/unit_tests/openvpn/test_crypto.c | 32 +++++ 5 files changed, 366 insertions(+), 130 deletions(-) diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h index 85cb084a..b72684ce 100644 --- a/src/openvpn/crypto_backend.h +++ b/src/openvpn/crypto_backend.h @@ -699,4 +699,23 @@ const char *translate_cipher_name_from_openvpn(const char *cipher_name); */ const char *translate_cipher_name_to_openvpn(const char *cipher_name); + +/** + * Calculates the TLS 1.0-1.1 PRF function. For the exact specification of the + * fun ction definition see the TLS RFCs like RFC 4346. + * + * @param seed seed to use + * @param seed_len length of the seed + * @param secret secret to use + * @param secret_len length of the secret + * @param output output destination + * @param output_len length of output/number of bytes to generate + */ +void +ssl_tls1_PRF(const uint8_t *seed, + int seed_len, + const uint8_t *secret, + int secret_len, + uint8_t *output, + int output_len); #endif /* CRYPTO_BACKEND_H_ */ diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index fbb1f120..dcdd964a 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -54,6 +54,7 @@ #include #include +#include /* @@ -984,4 +985,146 @@ memcmp_constant_time(const void *a, const void *b, size_t size) return diff; } +/* mbedtls-2.18.0 or newer */ +#ifdef HAVE_MBEDTLS_SSL_TLS_PRF +void +ssl_tls1_PRF(const uint8_t *seed, + int seed_len, + const uint8_t *secret, + int secret_len, + uint8_t *output, + int output_len) +{ + mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1, secret, secret_len, "", seed, + seed_len, output, output_len); +} +#else +/* + * Generate the hash required by for the \c tls1_PRF function. + * + * @param md_kt Message digest to use + * @param sec Secret to base the hash on + * @param sec_len Length of the secret + * @param seed Seed to hash + * @param seed_len Length of the seed + * @param out Output buffer + * @param olen Length of the output buffer + */ +static void +tls1_P_hash(const md_kt_t *md_kt, + const uint8_t *sec, + int sec_len, + const uint8_t *seed, + int seed_len, + uint8_t *out, + int olen) +{ + struct gc_arena gc = gc_new(); + uint8_t A1[MAX_HMAC_KEY_LENGTH]; + +#ifdef ENABLE_DEBUG + const int olen_orig = olen; + const uint8_t *out_orig = out; +#endif + + hmac_ctx_t *ctx = hmac_ctx_new(); + hmac_ctx_t *ctx_tmp = hmac_ctx_new(); + + dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc)); + dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc)); + + int chunk = md_kt_size(md_kt); + unsigned int A1_len = md_kt_size(md_kt); + + hmac_ctx_init(ctx, sec, sec_len, md_kt); + hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt); + + hmac_ctx_update(ctx,seed,seed_len); + hmac_ctx_final(ctx, A1); + + for (;; ) + { + hmac_ctx_reset(ctx); + hmac_ctx_reset(ctx_tmp); + hmac_ctx_update(ctx,A1,A1_len); + hmac_ctx_update(ctx_tmp,A1,A1_len); + hmac_ctx_update(ctx,seed,seed_len); + + if (olen > chunk) + { + hmac_ctx_final(ctx, out); + out += chunk; + olen -= chunk; + hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */ + } + else /* last one */ + { + hmac_ctx_final(ctx, A1); + memcpy(out,A1,olen); + break; + } + } + hmac_ctx_cleanup(ctx); + hmac_ctx_free(ctx); + hmac_ctx_cleanup(ctx_tmp); + hmac_ctx_free(ctx_tmp); + secure_memzero(A1, sizeof(A1)); + + dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc)); + gc_free(&gc); +} + +/* + * Use the TLS PRF function for generating data channel keys. + * This code is based on the OpenSSL library. + * + * TLS generates keys as such: + * + * master_secret[48] = PRF(pre_master_secret[48], "master secret", + * ClientHello.random[32] + ServerHello.random[32]) + * + * key_block[] = PRF(SecurityParameters.master_secret[48], + * "key expansion", + * SecurityParameters.server_random[32] + + * SecurityParameters.client_random[32]); + * + * Notes: + * + * (1) key_block contains a full set of 4 keys. + * (2) The pre-master secret is generated by the client. + */ +void +ssl_tls1_PRF(const uint8_t *label, + int label_len, + const uint8_t *sec, + int slen, + uint8_t *out1, + int olen) +{ + struct gc_arena gc = gc_new(); + const md_kt_t *md5 = md_kt_get("MD5"); + const md_kt_t *sha1 = md_kt_get("SHA1"); + + uint8_t *out2 = (uint8_t *) gc_malloc(olen, false, &gc); + + int len = slen/2; + const uint8_t *S1 = sec; + const uint8_t *S2 = &(sec[len]); + len += (slen&1); /* add for odd, make longer */ + + tls1_P_hash(md5,S1,len,label,label_len,out1,olen); + tls1_P_hash(sha1,S2,len,label,label_len,out2,olen); + + for (int i = 0; i #include #include - +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#include +#endif /* * Check for key size creepage. */ @@ -1121,4 +1123,172 @@ engine_load_key(const char *file, SSL_CTX *ctx) #endif /* if HAVE_OPENSSL_ENGINE */ } +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +void +ssl_tls1_PRF(const uint8_t *seed, + int seed_len, + const uint8_t *secret, + int secret_len, + uint8_t *output, + int output_len) +{ + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); + ASSERT(EVP_PKEY_derive_init(pctx) == 1); + + ASSERT(EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_md5_sha1()) == 1); + + ASSERT(EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret, secret_len) == 1); + + ASSERT(EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seed_len) == 1); + + size_t out_len = output_len; + ASSERT (EVP_PKEY_derive(pctx, output, &out_len) == 1); + ASSERT (out_len == output_len); +} +#else +/* + * Generate the hash required by for the \c tls1_PRF function. + * + * We cannot use our normal hmac_* function as they do not work + * in a FIPS environment and need to use the EVP_MD_* API, which + * + * The function below is adapted from OpenSSL 1.0.2t + * + * @param md_kt Message digest to use + * @param sec Secret to base the hash on + * @param sec_len Length of the secret + * @param seed Seed to hash + * @param seed_len Length of the seed + * @param out Output buffer + * @param olen Length of the output buffer + */ +static +int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, + int sec_len, + const void *seed, int seed_len, + unsigned char *out, int olen) +{ + int chunk; + size_t j; + EVP_MD_CTX ctx, ctx_tmp, ctx_init; + EVP_PKEY *mac_key; + unsigned char A1[EVP_MAX_MD_SIZE]; + size_t A1_len; + int ret = 0; + + chunk = EVP_MD_size(md); + OPENSSL_assert(chunk >= 0); + + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_init(&ctx_tmp); + EVP_MD_CTX_init(&ctx_init); + EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); + if (!mac_key) + goto err; + if (!EVP_DigestSignInit(&ctx_init, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) + goto err; + if (!EVP_DigestSignUpdate(&ctx, seed, seed_len)) + goto err; + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + + for (;;) { + /* Reinit mac contexts */ + if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) + goto err; + if (!EVP_DigestSignUpdate(&ctx, A1, A1_len)) + goto err; + if (olen > chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx)) + goto err; + if (!EVP_DigestSignUpdate(&ctx, seed, seed_len)) + goto err; + + if (olen > chunk) + { + if (!EVP_DigestSignFinal(&ctx, out, &j)) + goto err; + out += j; + olen -= j; + /* calc the next A1 value */ + if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len)) + goto err; + } + else + { + /* last one */ + + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + memcpy(out, A1, olen); + break; + } + } + ret = 1; +err: + EVP_PKEY_free(mac_key); + EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_cleanup(&ctx_tmp); + EVP_MD_CTX_cleanup(&ctx_init); + OPENSSL_cleanse(A1, sizeof(A1)); + return ret; +} + + +/* + * Use the TLS PRF function for generating data channel keys. + * This code is based on the OpenSSL library. + * + * TLS generates keys as such: + * + * master_secret[48] = PRF(pre_master_secret[48], "master secret", + * ClientHello.random[32] + ServerHello.random[32]) + * + * key_block[] = PRF(SecurityParameters.master_secret[48], + * "key expansion", + * SecurityParameters.server_random[32] + + * SecurityParameters.client_random[32]); + * + * Notes: + * + * (1) key_block contains a full set of 4 keys. + * (2) The pre-master secret is generated by the client. + */ +void +ssl_tls1_PRF(const uint8_t *label, + int label_len, + const uint8_t *sec, + int slen, + uint8_t *out1, + int olen) +{ + struct gc_arena gc = gc_new(); + /* For some reason our md_kt_get("MD5") fails otherwise in the unit test */ + const md_kt_t *md5 = EVP_md5(); + const md_kt_t *sha1 = EVP_sha1(); + + uint8_t *out2 = (uint8_t *) gc_malloc(olen, false, &gc); + + int len = slen/2; + const uint8_t *S1 = sec; + const uint8_t *S2 = &(sec[len]); + len += (slen&1); /* add for odd, make longer */ + + ASSERT(tls1_P_hash(md5,S1,len,label,label_len,out1,olen)); + ASSERT(tls1_P_hash(sha1,S2,len,label,label_len,out2,olen)); + + for (int i = 0; iserver, "Server"); } -/* - * Generate the hash required by for the \c tls1_PRF function. - * - * @param md_kt Message digest to use - * @param sec Secret to base the hash on - * @param sec_len Length of the secret - * @param seed Seed to hash - * @param seed_len Length of the seed - * @param out Output buffer - * @param olen Length of the output buffer - */ -static void -tls1_P_hash(const md_kt_t *md_kt, - const uint8_t *sec, - int sec_len, - const uint8_t *seed, - int seed_len, - uint8_t *out, - int olen) -{ - struct gc_arena gc = gc_new(); - uint8_t A1[MAX_HMAC_KEY_LENGTH]; - -#ifdef ENABLE_DEBUG - const int olen_orig = olen; - const uint8_t *out_orig = out; -#endif - - hmac_ctx_t *ctx = hmac_ctx_new(); - hmac_ctx_t *ctx_tmp = hmac_ctx_new(); - - dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc)); - dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc)); - - int chunk = md_kt_size(md_kt); - unsigned int A1_len = md_kt_size(md_kt); - - hmac_ctx_init(ctx, sec, sec_len, md_kt); - hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt); - - hmac_ctx_update(ctx,seed,seed_len); - hmac_ctx_final(ctx, A1); - - for (;; ) - { - hmac_ctx_reset(ctx); - hmac_ctx_reset(ctx_tmp); - hmac_ctx_update(ctx,A1,A1_len); - hmac_ctx_update(ctx_tmp,A1,A1_len); - hmac_ctx_update(ctx,seed,seed_len); - - if (olen > chunk) - { - hmac_ctx_final(ctx, out); - out += chunk; - olen -= chunk; - hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */ - } - else /* last one */ - { - hmac_ctx_final(ctx, A1); - memcpy(out,A1,olen); - break; - } - } - hmac_ctx_cleanup(ctx); - hmac_ctx_free(ctx); - hmac_ctx_cleanup(ctx_tmp); - hmac_ctx_free(ctx_tmp); - secure_memzero(A1, sizeof(A1)); - - dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc)); - gc_free(&gc); -} - -/* - * Use the TLS PRF function for generating data channel keys. - * This code is based on the OpenSSL library. - * - * TLS generates keys as such: - * - * master_secret[48] = PRF(pre_master_secret[48], "master secret", - * ClientHello.random[32] + ServerHello.random[32]) - * - * key_block[] = PRF(SecurityParameters.master_secret[48], - * "key expansion", - * SecurityParameters.server_random[32] + - * SecurityParameters.client_random[32]); - * - * Notes: - * - * (1) key_block contains a full set of 4 keys. - * (2) The pre-master secret is generated by the client. - */ -static void -tls1_PRF(const uint8_t *label, - int label_len, - const uint8_t *sec, - int slen, - uint8_t *out1, - int olen) -{ - struct gc_arena gc = gc_new(); - const md_kt_t *md5 = md_kt_get("MD5"); - const md_kt_t *sha1 = md_kt_get("SHA1"); - - uint8_t *out2 = (uint8_t *) gc_malloc(olen, false, &gc); - - int len = slen/2; - const uint8_t *S1 = sec; - const uint8_t *S2 = &(sec[len]); - len += (slen&1); /* add for odd, make longer */ - - tls1_P_hash(md5,S1,len,label,label_len,out1,olen); - tls1_P_hash(sha1,S2,len,label,label_len,out2,olen); - - for (int i = 0; i #include "crypto.h" +#include "ssl_backend.h" #include "mock_msg.h" @@ -136,12 +137,43 @@ crypto_translate_cipher_names(void **state) test_cipher_names("id-aes256-GCM", "AES-256-GCM"); } + +static uint8_t good_prf[32] = {0xd9, 0x8c, 0x85, 0x18, 0xc8, 0x5e, 0x94, 0x69, + 0x27, 0x91, 0x6a, 0xcf, 0xc2, 0xd5, 0x92, 0xfb, + 0xb1, 0x56, 0x7e, 0x4b, 0x4b, 0x14, 0x59, 0xe6, + 0xa9, 0x04, 0xac, 0x2d, 0xda, 0xb7, 0x2d, 0x67}; +static void +crypto_test_tls_prf(void **state) +{ + const char *seedstr = "Quis aute iure reprehenderit in voluptate " + "velit esse cillum dolore"; + const unsigned char *seed = (const unsigned char *) seedstr; + const size_t seed_len = strlen(seedstr); + + + + + const char* ipsumlorem = "Lorem ipsum dolor sit amet, consectetur " + "adipisici elit, sed eiusmod tempor incidunt ut " + "labore et dolore magna aliqua."; + + const unsigned char *secret = (const unsigned char *) ipsumlorem; + size_t secret_len = strlen((const char *)secret); + + + uint8_t out[32]; + ssl_tls1_PRF(seed, seed_len, secret, secret_len, out, sizeof(out)); + + assert_memory_equal(good_prf, out, sizeof(out)); +} + int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(crypto_pem_encode_decode_loopback), cmocka_unit_test(crypto_translate_cipher_names), + cmocka_unit_test(crypto_test_tls_prf) }; #if defined(ENABLE_CRYPTO_OPENSSL)