From patchwork Wed Oct 8 12:37:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4483 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:7d42:b0:72f:f16c:e055 with SMTP id fr2csp901066mab; Wed, 8 Oct 2025 05:38:16 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWW49O6b1KhGuEbncrkbLuQsipjt3h7yklld2lhHRk05s1VvPrhAhMomcN1AL0T6KofAtRlQAh21vo=@openvpn.net X-Google-Smtp-Source: AGHT+IHUjgyhExacc8+B3xCnMu3mEZS4/aweUUZtK+Mh7uTRRPZL0EQaPaHvEuQoDdclJsvFsDaZ X-Received: by 2002:a05:6830:6106:b0:7ae:39a2:2656 with SMTP id 46e09a7af769-7c0df7b6143mr1897154a34.25.1759927096500; Wed, 08 Oct 2025 05:38:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1759927096; cv=none; d=google.com; s=arc-20240605; b=iG04+/VkAkB2kDwYLG09lOxuTo8PWhuD7eluwQ/eerp2qa0SjSPBExyrAhIOJ23qzH Umk1SONftwWx/035Sh62F9FNIOaSh04ie86O/GqWG+z6zFJpEGoN/YNKLtOzyYfGfbsy H5gAuyuCLpkkfENx04yObAjPeHXKuNlgn5lBAtow8jkQgZapGAMH4esq9ASzZq7d8NYi dtERn43MqRFdsMopfiYP1Qp4um2T53ozfG9nkeDAx063/dAgsAndsFGVSUKQJd7djwo5 6Bvn70NfFin8YoXa1Le0r0SdZDxGnUrMZ60yXiR9u+O0FDQLM9245SymGaAfXlUEyt4E tBHA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; 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:dkim-signature; bh=Xp46iNVk8QIiBISw52/boT6BwPGNQ9ehV002rikkaX0=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=aWxzWgjsfAdI2b5/lSSF1mey7O2e2GSdaRtuvsFULi3L2NvarftKY1TKc4OL0z/M7y RG6Ant/4lo7tgdfTM+InWRe4w1z3zgHKoB5rgwSzta7lPdbcsjfGhRfwk4W7wiyZLx/S oGzBpoAGkI6gRJDEmVXAMZHyBnIcsFspq4C8QY11dWGHuw7TXOCTClvaDmlzgnU2cdkh xkzENOGSI61e0oXVgBdUk35axt6egc0HuYp8J3vpDrNIzcfa1qD2TiSyItzL865JT++G cZ+36UOTRUas5+OyL7Ga7rrqagIz+JiXC1YT1K/Ygx2dqYrHM/xp+oEmquq6O9tMVEsD TJsA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=hyt5Wqbo; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="Pwwop/NH"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=OHI9cBLj; 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 46e09a7af769-7c06bf3c8f4si1422516a34.358.2025.10.08.05.38.16 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Oct 2025 05:38:16 -0700 (PDT) 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=pass header.i=@lists.sourceforge.net header.s=beta header.b=hyt5Wqbo; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="Pwwop/NH"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=OHI9cBLj; 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 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Xp46iNVk8QIiBISw52/boT6BwPGNQ9ehV002rikkaX0=; b=hyt5Wqbog+15/qEsdX7W35Fpqb zHmrcW09GjA47io+rNO2NxUkfLUFtGKetanYC4UHlcya3oEK+gw4/jcFDwNFNE7f5Lo89tAuHHueD pD4YJZthgMr5tuvT/skF9VkrWxBCc6ESN614oO8glqZoo/2EqNYkYALQXuzZvWUNlemA=; 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 1v6TQq-0003Bq-Qq; Wed, 08 Oct 2025 12:38:13 +0000 Received: from [172.30.29.66] (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 1v6TQo-0003Ba-84 for openvpn-devel@lists.sourceforge.net; Wed, 08 Oct 2025 12:38:11 +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=QFnX2OKB4aCsZAMWeQr6Y5y388IA1snIeNKqULmBFbA=; b=Pwwop/NHqgnpLsoNeKjQxe6o7h Y9xVLNKteozbQ5dDqBYebPFV1dxCp0xfdRCCvDk8IwwpkQmpver68wF7uJ7da6fveVNPQimuKcfGI Agjzpxw1k1I/kEOsbsAlkEhZm5D7sc5nyDXycoqX4wJOWTkRgoozZHfabNzukXZLXVNI=; 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=QFnX2OKB4aCsZAMWeQr6Y5y388IA1snIeNKqULmBFbA=; b=OHI9cBLjgO7cfLbx7A5a75k+hb sJEwvwNO8c0uBxfQNXuOgQ8I93k5ZeVZ/F6Jj4qPY40pSBlRWGfuIm9m9W1fvmxakFSBHL8A9/aaM B7kBBsJ0lrkwGwl8owEQuoSy7s+0q6OrNaIifxaahTTeX+gTJBHlPMiCigBLpenihTf0=; Received: from [193.149.48.134] (helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1v6TQn-00079o-Mv for openvpn-devel@lists.sourceforge.net; Wed, 08 Oct 2025 12:38:10 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.18.1/8.18.1) with ESMTP id 598CbvwG018687 for ; Wed, 8 Oct 2025 14:37:57 +0200 Received: (from gert@localhost) by blue.greenie.muc.de (8.18.1/8.18.1/Submit) id 598Cbvh3018686 for openvpn-devel@lists.sourceforge.net; Wed, 8 Oct 2025 14:37:57 +0200 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Wed, 8 Oct 2025 14:37:51 +0200 Message-ID: <20251008123757.18670-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.49.1 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.3 (+) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", 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: Lev Stipakov Starting from 2.8.0, dco-win driver supports epoch data channel. This adds missing userspace part. While on it, fix broken assert introduced in e77c34. Key-Id 0 is a perfectly valid. Content analysis details: (1.3 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1v6TQn-00079o-Mv Subject: [Openvpn-devel] [PATCH v5] dco-win: support for epoch data channel 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?1845417315127804113?= X-GMAIL-MSGID: =?utf-8?q?1845417315127804113?= From: Lev Stipakov Starting from 2.8.0, dco-win driver supports epoch data channel. This adds missing userspace part. While on it, fix broken assert introduced in e77c34. Key-Id 0 is a perfectly valid. Change-Id: Ib5ed5969dcd405a47e34ed8479b7ffaaa5c43080 Signed-off-by: Lev Stipakov Acked-by: Arne Schwabe Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1219 --- 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/+/1219 This mail reflects revision 5 of this Change. Acked-by according to Gerrit (reflected above): Arne Schwabe diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c index 6afc680..8fb4662 100644 --- a/src/openvpn/dco.c +++ b/src/openvpn/dco.c @@ -56,8 +56,9 @@ const char *ciphername) { - msg(D_DCO_DEBUG, "%s: peer_id=%d keyid=%d, currently %d keys installed", __func__, - multi->dco_peer_id, ks->key_id, multi->dco_keys_installed); + bool epoch = ks->crypto_options.flags & CO_EPOCH_DATA_KEY_FORMAT; + msg(D_DCO_DEBUG, "%s: peer_id=%d keyid=%d epoch=%d, currently %d keys installed", __func__, + multi->dco_peer_id, ks->key_id, multi->dco_keys_installed, epoch); /* Install a key in the PRIMARY slot only when no other key exist. * From that moment on, any new key will be installed in the SECONDARY @@ -71,7 +72,7 @@ } int ret = dco_new_key(multi->dco, multi->dco_peer_id, ks->key_id, slot, encrypt_key, encrypt_iv, - decrypt_key, decrypt_iv, ciphername); + decrypt_key, decrypt_iv, ciphername, epoch); if ((ret == 0) && (multi->dco_keys_installed < 2)) { multi->dco_keys_installed++; diff --git a/src/openvpn/dco.h b/src/openvpn/dco.h index a362977..e5e8709 100644 --- a/src/openvpn/dco.h +++ b/src/openvpn/dco.h @@ -251,11 +251,8 @@ * Return whether the dco implementation supports the new protocol features of * a 64 bit packet counter and AEAD tag at the end. */ -static inline bool -dco_supports_epoch_data(struct context *c) -{ - return false; -} +bool +dco_supports_epoch_data(struct context *c); #else /* if defined(ENABLE_DCO) */ typedef void *dco_context_t; diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c index b9f6bc7..947a769 100644 --- a/src/openvpn/dco_freebsd.c +++ b/src/openvpn/dco_freebsd.c @@ -487,14 +487,14 @@ int dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid, dco_key_slot_t slot, const uint8_t *encrypt_key, const uint8_t *encrypt_iv, const uint8_t *decrypt_key, - const uint8_t *decrypt_iv, const char *ciphername) + const uint8_t *decrypt_iv, const char *ciphername, bool epoch) { struct ifdrv drv; nvlist_t *nvl, *encrypt_nvl, *decrypt_nvl; int ret; - msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %d, cipher %s", __func__, slot, keyid, peerid, - ciphername); + msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %d, cipher %s, epoch %d", __func__, slot, keyid, peerid, + ciphername, epoch); nvl = nvlist_create(0); @@ -876,4 +876,10 @@ return "none:AES-256-GCM:AES-192-GCM:AES-128-GCM:CHACHA20-POLY1305"; } +bool +dco_supports_epoch_data(struct context *c) +{ + return false; +} + #endif /* defined(ENABLE_DCO) && defined(TARGET_FREEBSD) */ diff --git a/src/openvpn/dco_internal.h b/src/openvpn/dco_internal.h index 86af003..97a7048 100644 --- a/src/openvpn/dco_internal.h +++ b/src/openvpn/dco_internal.h @@ -66,7 +66,7 @@ int dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid, dco_key_slot_t slot, const uint8_t *encrypt_key, const uint8_t *encrypt_iv, const uint8_t *decrypt_key, - const uint8_t *decrypt_iv, const char *ciphername); + const uint8_t *decrypt_iv, const char *ciphername, bool epoch); int dco_del_key(dco_context_t *dco, unsigned int peerid, dco_key_slot_t slot); diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c index d46fa46..0ae30b1 100644 --- a/src/openvpn/dco_linux.c +++ b/src/openvpn/dco_linux.c @@ -596,10 +596,10 @@ int dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid, dco_key_slot_t slot, const uint8_t *encrypt_key, const uint8_t *encrypt_iv, const uint8_t *decrypt_key, - const uint8_t *decrypt_iv, const char *ciphername) + const uint8_t *decrypt_iv, const char *ciphername, bool epoch) { - msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %d, cipher %s", __func__, slot, keyid, peerid, - ciphername); + msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %d, cipher %s, epoch %d", __func__, slot, keyid, peerid, + ciphername, epoch); const int key_len = cipher_kt_key_size(ciphername); const int nonce_tail_len = 8; @@ -1298,4 +1298,10 @@ return "AES-128-GCM:AES-256-GCM:AES-192-GCM:CHACHA20-POLY1305"; } +bool +dco_supports_epoch_data(struct context *c) +{ + return false; +} + #endif /* defined(ENABLE_DCO) && defined(TARGET_LINUX) */ diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c index 30307de..ca5eedf 100644 --- a/src/openvpn/dco_win.c +++ b/src/openvpn/dco_win.c @@ -528,7 +528,7 @@ int dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid, dco_key_slot_t slot, const uint8_t *encrypt_key, const uint8_t *encrypt_iv, const uint8_t *decrypt_key, - const uint8_t *decrypt_iv, const char *ciphername) + const uint8_t *decrypt_iv, const char *ciphername, bool epoch) { msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %d, cipher %s", __func__, slot, keyid, peerid, ciphername); @@ -537,29 +537,42 @@ size_t key_len = cipher_kt_key_size(ciphername); ASSERT(key_len <= 32); - OVPN_CRYPTO_DATA crypto_data; + OVPN_CRYPTO_DATA_V2 crypto_data; ZeroMemory(&crypto_data, sizeof(crypto_data)); - crypto_data.CipherAlg = dco_get_cipher(ciphername); + OVPN_CRYPTO_DATA *v1 = &crypto_data.V1; + + v1->CipherAlg = dco_get_cipher(ciphername); ASSERT(keyid >= 0 && keyid <= UCHAR_MAX); - crypto_data.KeyId = (unsigned char)keyid; - crypto_data.PeerId = peerid; - crypto_data.KeySlot = slot; + v1->KeyId = (unsigned char)keyid; + v1->PeerId = peerid; + v1->KeySlot = slot; - CopyMemory(crypto_data.Encrypt.Key, encrypt_key, key_len); - crypto_data.Encrypt.KeyLen = (unsigned char)key_len; - CopyMemory(crypto_data.Encrypt.NonceTail, encrypt_iv, nonce_len); + /* for epoch we use key material as a seed, no as actual key */ + CopyMemory(v1->Encrypt.Key, encrypt_key, epoch ? 32 : key_len); + v1->Encrypt.KeyLen = (unsigned char)key_len; + CopyMemory(v1->Encrypt.NonceTail, encrypt_iv, nonce_len); - CopyMemory(crypto_data.Decrypt.Key, decrypt_key, key_len); - crypto_data.Decrypt.KeyLen = (unsigned char)key_len; - CopyMemory(crypto_data.Decrypt.NonceTail, decrypt_iv, nonce_len); + CopyMemory(v1->Decrypt.Key, decrypt_key, epoch ? 32 : key_len); + v1->Decrypt.KeyLen = (unsigned char)key_len; + CopyMemory(v1->Decrypt.NonceTail, decrypt_iv, nonce_len); - ASSERT(crypto_data.CipherAlg > 0); + ASSERT(v1->CipherAlg > 0); + + DWORD ioctl = OVPN_IOCTL_NEW_KEY; + VOID *buf = &crypto_data.V1; + DWORD bufSize = sizeof(crypto_data.V1); + if (epoch) + { + ioctl = OVPN_IOCTL_NEW_KEY_V2; + crypto_data.CryptoOptions |= CRYPTO_OPTIONS_EPOCH; + buf = &crypto_data; + bufSize = sizeof(crypto_data); + } DWORD bytes_returned = 0; - if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_NEW_KEY, &crypto_data, sizeof(crypto_data), NULL, - 0, &bytes_returned, NULL)) + if (!DeviceIoControl(dco->tt->hand, ioctl, buf, bufSize, NULL, 0, &bytes_returned, NULL)) { msg(M_ERR, "DeviceIoControl(OVPN_IOCTL_NEW_KEY) failed"); return -1; @@ -1076,4 +1089,11 @@ gc_free(&gc); } +bool +dco_supports_epoch_data(struct context *c) +{ + OVPN_VERSION ver = { 0 }; + return dco_get_version(&ver) && ((ver.Major == 2 && ver.Minor >= 8) || (ver.Major > 2)); +} + #endif /* defined(_WIN32) */ diff --git a/src/openvpn/ovpn_dco_win.h b/src/openvpn/ovpn_dco_win.h index 9e1378a..e76770b 100644 --- a/src/openvpn/ovpn_dco_win.h +++ b/src/openvpn/ovpn_dco_win.h @@ -118,6 +118,13 @@ int PeerId; } OVPN_CRYPTO_DATA, * POVPN_CRYPTO_DATA; +#define CRYPTO_OPTIONS_EPOCH (1<<1) + +typedef struct _OVPN_CRYPTO_DATA_V2 { + OVPN_CRYPTO_DATA V1; + UINT32 CryptoOptions; +} OVPN_CRYPTO_DATA_V2, * POVPN_CRYPTO_DATA_V2; + typedef struct _OVPN_MP_SET_PEER { int PeerId; LONG KeepaliveInterval;