From patchwork Fri Nov 17 09:14:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 3449 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7300:50e4:b0:f2:62eb:61c1 with SMTP id r4csp306643dyd; Fri, 17 Nov 2023 01:15:40 -0800 (PST) X-Google-Smtp-Source: AGHT+IEX5A2UtD9ig5xLH59uTOOoZKpUlhali8Vl3JsWqdAFbkez4F/8L6pFFEOKcYNGGTqKOGd+ X-Received: by 2002:a05:6a20:3d09:b0:187:865f:b3d4 with SMTP id y9-20020a056a203d0900b00187865fb3d4mr6765262pzi.6.1700212540187; Fri, 17 Nov 2023 01:15:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700212540; cv=none; d=google.com; s=arc-20160816; b=udhxGylPhAz9FsAVeEoOoxxJvIbkMjfw1ujyM/jIdQUtkb2cGrl8SbCayuVdzFZNt5 vYwltt+MSEVUKG7DqhqMLua3aea5FJBAUf4hY4K5t9km0plN58bGMlC09AdhwUer3eMa XUmZQHygfJ/fkvU+AT8uiMYpKjq+TIGMYLhCOjqI1N/E709h1BC/GVk7XiR5t8OHbvO1 jsKp7XNYVa/oxC9RaayCbj5GBNFbbaBt3s5tNNoMsZ6XkfGA6CLM5igAWLruweJuFDIc IoSSDfIKT2XqkZgwwmrM9FzVlbXPVqK4gyc+MnxIHpwvbfn1sm9BoxhBoNAaJxnIUYg6 ikDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature; bh=SlHq3HV9H+iM2B4zh2wVIMhjS3oG/h9Xtgf2u5YiPQY=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=FLpBeEm23NIywRk09oBjFRad4HYCKebslwySNTmUFqAfjA1J8zIxNWM88eseeyYxS1 LGrDfAM4XmLjpOTlfB1+EjEErW1JiZlLViBplyu1dE+t9nuZEOY3gqJhe3FNUSkX3qTs lXFSY3O6h8b299LYrv9NoofAgnmGxpAqXmIKdnvCy6UNJAn7BqNhnLmlsNwnMDqqbb/4 +tHnNfwGdOde39FpnwZucXOtaBIYdVUwwCLl2y7sRgvCQvdwx5hC61+lCkQkLsKYhTYU jyQ9xLtgAUT9bu4xgzCXrftVazHly3LAl9p2kowlJeoFBHx9HJ7gDh1D89ichrYualbS SLWg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=F5JwWw4q; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=mBcf9sOP; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id x1-20020a63fe41000000b005b8de051ac6si1487589pgj.111.2023.11.17.01.15.39 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Nov 2023 01:15:40 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=F5JwWw4q; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=mBcf9sOP; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de 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.95) (envelope-from ) id 1r3uvq-0002Qn-Ac; Fri, 17 Nov 2023 09:14:33 +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.95) (envelope-from ) id 1r3uvY-0002Po-Q7 for openvpn-devel@lists.sourceforge.net; Fri, 17 Nov 2023 09:14:20 +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:To:From:Sender:Reply-To:Cc: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=gPoIyn0uFEIpFQjQSDe/NXav3H80H65V1sQKnU8ztAk=; b=F5JwWw4qZEOSxLds7HBa/5rQT6 JsVQ0UgX9Lz9gCIanJzudBxYjaaffRiQx+nrgGtyyHNq5ji01FMxQRcGe4FFOEx0Y0JK4KP9KcPH/ r4sPGat8EYTM1bqmD/EJCq4jZmRoY/w3kVuQ4CnRPFOkvsgaX9B70qkHjPFGPvTqfkag=; 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:To:From:Sender:Reply-To:Cc: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=gPoIyn0uFEIpFQjQSDe/NXav3H80H65V1sQKnU8ztAk=; b=mBcf9sOPcckA2RJAzQI6QV3BmM kImKZGdYIT8p4cG7r7zRKLrkwZ5+Q7rIpbLKYSigfdyp9GbEh0SXFo3ii4q5qhyTpJSv7OkH5t2Ti p5zvyWgh57g9M0UX1qL3yVG+RIodHLZ1gIHqvdbMYpwJSJH1V2n8pDhlfeaG6/T77XsE=; Received: from [193.149.48.174] (helo=blue.greenie.muc.de) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1r3uvU-008Ecp-SK for openvpn-devel@lists.sourceforge.net; Fri, 17 Nov 2023 09:14:15 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.17.1.9/8.17.1.9) with ESMTP id 3AH9E2o9025803 for ; Fri, 17 Nov 2023 10:14:03 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 3AH9E2Wm025802 for openvpn-devel@lists.sourceforge.net; Fri, 17 Nov 2023 10:14:02 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Fri, 17 Nov 2023 10:14:01 +0100 Message-ID: <20231117091401.25793-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.3 (+) 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: From: Max Fillinger Change-Id: I8e90530726b7f7ba3cee0438f2d81a1ac42e821b Signed-off-by: Max Fillinger Acked-by: Frank Lichtenheld --- Content analysis details: (1.3 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.0 T_SCC_BODY_TEXT_LINE No description available. 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1r3uvU-008Ecp-SK Subject: [Openvpn-devel] [PATCH v5] Enable key export with mbed TLS 3.x.y 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1782802064367616206?= X-GMAIL-MSGID: =?utf-8?q?1782802064367616206?= From: Max Fillinger Change-Id: I8e90530726b7f7ba3cee0438f2d81a1ac42e821b Signed-off-by: Max Fillinger Acked-by: Frank Lichtenheld --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/402 This mail reflects revision 5 of this Change. Acked-by according to Gerrit (reflected above): Frank Lichtenheld diff --git a/config.h.cmake.in b/config.h.cmake.in index 1c0dd6f..19b79bc 100644 --- a/config.h.cmake.in +++ b/config.h.cmake.in @@ -387,7 +387,10 @@ #undef HAVE_VSNPRINTF /* we always assume a recent mbed TLS version */ -#define HAVE_CTR_DRBG_UPDATE_RET 1 +#define HAVE_MBEDTLS_PSA_CRYPTO_H 1 +#define HAVE_MBEDTLS_SSL_TLS_PRF 1 +#define HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB 1 +#define HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET 1 /* Path to ifconfig tool */ #define IFCONFIG_PATH "@IFCONFIG_PATH@" diff --git a/configure.ac b/configure.ac index 7e5763d..84eaad6 100644 --- a/configure.ac +++ b/configure.ac @@ -1025,11 +1025,11 @@ [AC_MSG_ERROR([mbed TLS version >= 2.0.0 or >= 3.2.1 required])] ) - AC_CHECK_HEADER( - psa/crypto.h, - [AC_DEFINE([MBEDTLS_HAVE_PSA_CRYPTO_H], [1], [yes])], - [AC_DEFINE([MBEDTLS_HAVE_PSA_CRYPTO_H], [0], [no])] - ) + AC_CHECK_HEADER( + psa/crypto.h, + [AC_DEFINE([HAVE_MBEDTLS_PSA_CRYPTO_H], [1], [yes])], + [AC_DEFINE([HAVE_MBEDTLS_PSA_CRYPTO_H], [0], [no])] + ) AC_CHECK_FUNCS( [ \ @@ -1040,16 +1040,32 @@ [AC_MSG_ERROR([mbed TLS check for AEAD support failed])] ) + AC_CHECK_FUNC( + [mbedtls_ssl_tls_prf], + [AC_DEFINE([HAVE_MBEDTLS_SSL_TLS_PRF], [1], [yes])], + [AC_DEFINE([HAVE_MBEDTLS_SSL_TLS_PRF], [0], [no])] + ) + have_export_keying_material="yes" AC_CHECK_FUNC( [mbedtls_ssl_conf_export_keys_ext_cb], - , - [have_export_keying_material="no"] + [AC_DEFINE([HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB], [1], [yes])], + [AC_DEFINE([HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB], [0], [no])] ) + if test "x$ac_cv_func_mbedtls_ssl_conf_export_keys_ext_cb" != xyes; then + AC_CHECK_FUNC( + [mbedtls_ssl_set_export_keys_cb], + [AC_DEFINE([HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB], [1], [yes])], + [AC_DEFINE([HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB], [0], [no])] + ) + if test "x$ac_cv_func_mbedtls_ssl_set_export_keys_cb" != xyes; then + have_export_keying_material="no" + fi + fi AC_CHECK_FUNC( [mbedtls_ctr_drbg_update_ret], - AC_DEFINE([HAVE_CTR_DRBG_UPDATE_RET], [1], + AC_DEFINE([HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET], [1], [Use mbedtls_ctr_drbg_update_ret from mbed TLS]), ) diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index 52deef8..b953961 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -82,6 +82,7 @@ ovpn_dco_win.h \ platform.c platform.h \ console.c console.h console_builtin.c console_systemd.c \ + mbedtls_compat.h \ mroute.c mroute.h \ mss.c mss.h \ mstats.c mstats.h \ diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index aaf6ef7..ad3439c 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -989,8 +989,9 @@ return diff; } -/* mbedtls-2.18.0 or newer */ -#ifdef HAVE_MBEDTLS_SSL_TLS_PRF +/* mbedtls-2.18.0 or newer implements tls_prf, but prf_tls1 is removed + * from recent versions, so we use our own implementation if necessary. */ +#if HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1) bool ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret, int secret_len, uint8_t *output, int output_len) @@ -999,7 +1000,7 @@ secret_len, "", seed, seed_len, output, output_len)); } -#else /* ifdef HAVE_MBEDTLS_SSL_TLS_PRF */ +#else /* HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */ /* * Generate the hash required by for the \c tls1_PRF function. * @@ -1128,5 +1129,5 @@ gc_free(&gc); return true; } -#endif /* ifdef HAVE_MBEDTLS_SSL_TLS_PRF */ +#endif /* HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */ #endif /* ENABLE_CRYPTO_MBEDTLS */ diff --git a/src/openvpn/mbedtls_compat.h b/src/openvpn/mbedtls_compat.h index fe7c3f9..610215b 100644 --- a/src/openvpn/mbedtls_compat.h +++ b/src/openvpn/mbedtls_compat.h @@ -33,6 +33,8 @@ #ifndef MBEDTLS_COMPAT_H_ #define MBEDTLS_COMPAT_H_ +#include "syshead.h" + #include "errlevel.h" #include @@ -41,24 +43,25 @@ #include #include #include +#include #include #include -#if MBEDTLS_HAVE_PSA_CRYPTO_H +#if HAVE_MBEDTLS_PSA_CRYPTO_H #include #endif static inline void mbedtls_compat_psa_crypto_init(void) { -#if MBEDTLS_HAVE_PSA_CRYPTO_H && defined(MBEDTLS_PSA_CRYPTO_C) +#if HAVE_MBEDTLS_PSA_CRYPTO_H && defined(MBEDTLS_PSA_CRYPTO_C) if (psa_crypto_init() != PSA_SUCCESS) { msg(M_FATAL, "mbedtls: psa_crypto_init() failed"); } #else return; -#endif /* MBEDTLS_HAVE_PSA_CRYPTO_H && defined(MBEDTLS_PSA_CRYPTO_C) */ +#endif /* HAVE_MBEDTLS_PSA_CRYPTO_H && defined(MBEDTLS_PSA_CRYPTO_C) */ } /* @@ -74,14 +77,14 @@ const unsigned char *additional, size_t add_len) { -#if HAVE_CTR_DRBG_UPDATE_RET +#if HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET return mbedtls_ctr_drbg_update_ret(ctx, additional, add_len); #elif MBEDTLS_VERSION_NUMBER < 0x03020100 mbedtls_ctr_drbg_update(ctx, additional, add_len); return 0; #else return mbedtls_ctr_drbg_update(ctx, additional, add_len); -#endif /* HAVE_CTR_DRBG_UPDATE_RET */ +#endif /* HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET */ } static inline int diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index 4ece37e..5168484 100644 --- a/src/openvpn/ssl_mbedtls.c +++ b/src/openvpn/ssl_mbedtls.c @@ -173,6 +173,16 @@ } #ifdef HAVE_EXPORT_KEYING_MATERIAL + +#if HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB +/* + * Key export callback for older versions of mbed TLS, to be used with + * mbedtls_ssl_conf_export_keys_ext_cb(). It is called with the master + * secret, client random and server random, and the type of PRF function + * to use. + * + * Mbed TLS stores this callback in the mbedtls_ssl_config struct and it + * is used in the mbedtls_ssl_contexts set up from that config. */ int mbedtls_ssl_export_keys_cb(void *p_expkey, const unsigned char *ms, const unsigned char *kb, size_t maclen, @@ -193,8 +203,55 @@ memcpy(cache->master_secret, ms, sizeof(cache->master_secret)); cache->tls_prf_type = tls_prf_type; - return true; + return 0; } +#elif HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB +/* + * Key export callback for newer versions of mbed TLS, to be used with + * mbedtls_ssl_set_export_keys_cb(). When used with TLS 1.2, the callback + * is called with the TLS 1.2 master secret, client random, server random + * and the type of PRF to use. With TLS 1.3, it is called with several + * different keys (indicated by type), but unfortunately not the exporter + * master secret. + * + * Unlike in older versions, the callback is not stored in the + * mbedtls_ssl_config. It is placed in the mbedtls_ssl_context after it + * has been set up. */ +void +mbedtls_ssl_export_keys_cb(void *p_expkey, + mbedtls_ssl_key_export_type type, + const unsigned char *secret, + size_t secret_len, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type) +{ + /* Since we can't get the TLS 1.3 exporter master secret, we ignore all key + * types except MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET. */ + if (type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET) + { + return; + } + + struct tls_session *session = p_expkey; + struct key_state_ssl *ks_ssl = &session->key[KS_PRIMARY].ks_ssl; + struct tls_key_cache *cache = &ks_ssl->tls_key_cache; + + /* The TLS 1.2 master secret has a fixed size, so if secret_len has + * a different value, something is wrong with mbed TLS. */ + if (secret_len != sizeof(cache->master_secret)) + { + msg(M_FATAL, + "ERROR: Incorrect TLS 1.2 master secret length: Got %zu, expected %zu", + secret_len, sizeof(cache->master_secret)); + } + + memcpy(cache->client_server_random, client_random, 32); + memcpy(cache->client_server_random + 32, server_random, 32); + memcpy(cache->master_secret, secret, sizeof(cache->master_secret)); + cache->tls_prf_type = tls_prf_type; +} +#endif /* HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB */ bool key_state_export_keying_material(struct tls_session *session, @@ -1205,8 +1262,8 @@ mbedtls_ssl_conf_max_version(ks_ssl->ssl_config, major, minor); } -#ifdef HAVE_EXPORT_KEYING_MATERIAL - /* Initialize keying material exporter */ +#if HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB + /* Initialize keying material exporter, old style. */ mbedtls_ssl_conf_export_keys_ext_cb(ks_ssl->ssl_config, mbedtls_ssl_export_keys_cb, session); #endif @@ -1216,6 +1273,11 @@ mbedtls_ssl_init(ks_ssl->ctx); mbed_ok(mbedtls_ssl_setup(ks_ssl->ctx, ks_ssl->ssl_config)); +#if HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB + /* Initialize keying material exporter, new style. */ + mbedtls_ssl_set_export_keys_cb(ks_ssl->ctx, mbedtls_ssl_export_keys_cb, session); +#endif + /* Initialise BIOs */ ALLOC_OBJ_CLEAR(ks_ssl->bio_ctx, bio_ctx); mbedtls_ssl_set_bio(ks_ssl->ctx, ks_ssl->bio_ctx, ssl_bio_write,