From patchwork Thu Jul 2 11:52:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 30 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:1887:b0:869:83bc:8c48 with SMTP id r7csp550704max; Thu, 2 Jul 2026 04:53:26 -0700 (PDT) X-Forwarded-Encrypted: i=2; AFNElJ+P6M08Dh2nkUWj+eH2Q36n5MtkhcXO5OHyvwQWyVkmb/HfiknzUC6BhCiwRm0piz0gSWsX+jvU0Qo=@openvpn.net X-Received: by 2002:a05:6820:613:b0:6a1:44aa:86ce with SMTP id 006d021491bc7-6a309a132c6mr3336076eaf.22.1782993206209; Thu, 02 Jul 2026 04:53:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1782993206; cv=none; d=google.com; s=arc-20260327; b=q1MP0MWjOkmTqa7uWBdhX9FLG564FGQEp0CLt6+jwj+8j6twXCdPrexsj3FSsPhcjx 3PP/pKWSv2ZaQbyqR/y/V+hB2Di5xt2ADxDIlM4C0NpYcXIcY5aDqe3aOb6hw7auPU6v 5kYK1FuRYrwALreNKsOU+kJXpGXaiSsbo5ALBTZ0vuSzlfVEK4Wy9FXOpC6scif1/d8c r3vY7dgPRUH5S1bQiq8CudC7BMYT8KjcmFyKJHkwCkqhXDhz9/qgbU8GbrcEtW9brLsC rjQXc5BPd0yAKEE6akUzviGBnfZRzR3CGCV5QWtq5l0tTF67DgnBfeRBB+tm+EChWwXo vloA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:message-id:date:to:from:dkim-signature:dkim-signature :dkim-signature:dkim-signature; bh=XnSyhfsLXRr1uSCHVcfoTMmFUWjdGsJLW/kYe9XGA9w=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=kDxhRfg4+q0jFg4xTbEdHXvsjeQejwlbKOJYJ7cX7lHcdNCnV/gUJaLGPIyqKoi2Td A5nCtXm2uovQelDl8246JtLdzN/PNJaJk/DeQSK2cwmUl/yaZshzqtQrEtk7Y9odCFFc fdkNNpPeSWndW8JmRLMpH2gwn2zZpvN3lvFm2i+1x/CH12gSqF27udlksKBtGes2m2RE dwt9B1e4LAtye3Pevnb/A3N6jRH/elq7YZBaEoUgyoiBjaztI1P8ve0OOVLfMElR+q0j xtMlqSCQyhBszmjSkc5JDOLPmbHAVzcxSmw8fKfPOIglpWORZMN2RY7IlBRc9OVGXR2S isog==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=EnJYSj4e; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=M7zu9Xxm; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=XeEBPXiw; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=pmPwexwn; 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 Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 006d021491bc7-6a310385e92si2104624eaf.41.2026.07.02.04.53.25 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Jul 2026 04:53:26 -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=EnJYSj4e; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=M7zu9Xxm; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=XeEBPXiw; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=pmPwexwn; 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 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: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:In-Reply-To:References:List-Owner; bh=XnSyhfsLXRr1uSCHVcfoTMmFUWjdGsJLW/kYe9XGA9w=; b=EnJYSj4edLl65P2g8MrjkRO4D+ 0C+vN2XdsGIPCsCUv5FLJVnTvSFIAmoMpVEIAA+IvTheoIP+AEiJ9FnEdiGymM+mGMP0cjR8UnR2J PBtTcrAvMoAKEnsXnJ2MfA9Yc4a9YmRecIWOGunG6QriJ4xlnYssjxB+9qJvQ6BiWwCM=; Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wfFys-0001gd-BA; Thu, 02 Jul 2026 11:53:23 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wfFyr-0001gU-B4 for openvpn-devel@lists.sourceforge.net; Thu, 02 Jul 2026 11:53:22 +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=LzPkj0AgUZs1Pum16f8QFcc3ijPISLYlHYdqhZAkqCA=; b=M7zu9XxmBUSvNtffjG7K0AmQXm irN1SZE2pk6F+zpl3V1qshYcw/I7CTiRSoKyTACJiYEECUXVXyKYR4nsQTgNc8e8xAoP5uRkrGaPM UeqPrBO5qduqIW7UmBLOEqSD6D5PoAYuszXSzO9qeQ3rNFQ2TYxcrUyKzxut7drQFyXA=; 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=LzPkj0AgUZs1Pum16f8QFcc3ijPISLYlHYdqhZAkqCA=; b=X eEBPXiwzRy9YNk/eHRm7SouQDqz462oTLbBrh4kv8N8TURmezwFcPA2FzvbytCZCOi8jVfeI9P0EF 6gFI5xyYt1EBzveFbCYZUy3XC2XQGNdi4BArxhvflv+GrRIIZprSXjLAsYQxwStylwr2fyob6zCb9 C35Vafzn6YKYwMmQ=; Received: from mout-b-206.mailbox.org ([195.10.208.51]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wfFyo-0004JO-9n for openvpn-devel@lists.sourceforge.net; Thu, 02 Jul 2026 11:53:21 +0000 Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:b231:465::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-206.mailbox.org (Postfix) with ESMTPS id 4grZyT3MByz9xvn; Thu, 2 Jul 2026 13:53:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1782993185; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=LzPkj0AgUZs1Pum16f8QFcc3ijPISLYlHYdqhZAkqCA=; b=pmPwexwnRhjpA/umIEPxIQoCMrhNkTq01VbW170ZwNinXQWcKiAaF/lHXnnQ0hwhF9/2ff IlFpAEkTWvmSTbH1GW75Vhsck8JlEEWrE3y+J1JaviNHodUxIB8LZPF7JfP2+quDFrOWNY uNv/Eph6nwMU6OcXvHIniiMZQ/EMoQpM7WvVgNpQjSUj6XVMypS0Z+IdQUsfr39UUoHXr5 fsQmionCxQKs27neEFM6jciPWBW/93Iz3ZJicLBG2PA50rPdhtvfKhR6x0IKn1yHoC+CRx /2fCAHI/jzY4zGlmT4W/itGct+gielLoLv0uB9zl8lPRX3BiVZUYJfsplYG75w== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of ralf@mandelbit.com designates 2001:67c:2050:b231:465::2 as permitted sender) smtp.mailfrom=ralf@mandelbit.com From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Thu, 2 Jul 2026 13:52:15 +0200 Message-ID: MIME-Version: 1.0 X-Rspamd-Queue-Id: 4grZyT3MByz9xvn X-Spam-Score: -0.2 (/) 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: Hi, This is a respin of the series that adds support for OpenVPN epoch data channel keys to the ovpn kernel module. Epoch keys are described in the OpenVPN wire protocol draft: Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1wfFyo-0004JO-9n Subject: [Openvpn-devel] [RFC ovpn net-next v2 00/14] ovpn: add epoch data channel keys 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: 1869603883994257422 X-GMAIL-MSGID: 1869603883994257422 Hi, This is a respin of the series that adds support for OpenVPN epoch data channel keys to the ovpn kernel module. Epoch keys are described in the OpenVPN wire protocol draft: https://openvpn.github.io/openvpn-rfc/openvpn-wire-protocol.html#section-7.2 https://openvpn.github.io/openvpn-rfc/openvpn-wire-protocol.html#section-7.5 At a high level, epoch keys allow OpenVPN to rotate data-channel AEAD keys without requiring a full userspace renegotiation whenever a data-channel key reaches a usage or packet-ID limit. Instead of installing one concrete AEAD key and nonce tail per direction, userspace installs per-direction epoch PRKs. The kernel derives the concrete AEAD key and implicit IV for each epoch using the OpenVPN HKDF-Expand-Label construction, and can then move between pre-derived epochs in the data path. This is conceptually the same mechanism (D)TLS 1.3 already uses: OVPN-Expand-Label is TLS 1.3's HKDF-Expand-Label with an "ovpn " prefix instead of "tls13 ", and advancing an epoch is the data-channel analogue of a TLS 1.3 key update / DTLS 1.3 epoch increment. The DATA_V2 opcode is still used, but epoch packets use the extended packet ID layout defined by the draft: a 64-bit packet ID carrying a 16-bit epoch and a 48-bit sequence number, an XOR-based IV construction, and the AEAD tag at the end of the packet. Carrying the tag after the ciphertext, rather than prepending it as the direct-key format does, matches how AEAD implementations stream their output and lets the data path map payload and tag as a single contiguous scatterlist. The series is structured in three parts. The first adds packet-ID and AES-GCM usage-limit accounting. TX now notifies userspace before packet-ID wrap or AES-GCM hard exhaustion, and stops before the hard limit. RX accounts authenticated packets and reports threshold crossings without dropping packets solely because the peer crossed a local usage threshold. The series also limits AEAD decrypt verification failures. The middle part moves per-direction key state into explicit key contexts, makes those contexts refcounted for async crypto completion, and makes packet layout handling explicit. This keeps the epoch implementation from adding more special cases to the direct-key path. The epoch implementation keeps current TX/RX key contexts, one retiring RX key for reordered packets, and bounded rings of future TX/RX keys. TX rotates to a future key before hard packet-ID or AEAD usage exhaustion, and also rotates on the soft AEAD threshold. RX authenticates a packet with a future key before promoting that key to current, then refills consumed future-key slots from workqueue context. Selftest coverage is intentionally limited: the tests install epoch keys and verify steady-state UDP/TCP packet layout, including the epoch field in captured DATA_V2 packets. They do not exercise rotation or future-key refill because the production thresholds are cryptographic safety limits, so reaching them needs an enormous packet-ID/AEAD budget and lowering them would mean test-only knobs in security-sensitive data-path policy. The HKDF-Expand implementation added here (crypto_epoch.c) overlaps with the open-coded HKDF-Expand already carried by fscrypt and nvme. We intend to unify all three into a single shared helper in a follow-up series, rather than block this work on that refactor. Thanks, Ralf Lici Mandelbit Srl --- Changes since v1 https://lore.kernel.org/openvpn-devel/cover.1782919654.git.ralf@mandelbit.com/ - Address review findings by avoiding PRK advancement on failed future-key refill, zeroing derived key material on all epoch key creation paths, fixing epoch scatterlist sizing/termination, and preventing refill work from outliving module text. - Expand the cover letter based on Arne's suggestion. - Mention in the cover letter that we're aiming for a unified HKDF-Expand implementation as follow-up work. Ralf Lici (14): ovpn: prepare packet ID state for usage limits ovpn: enforce AES-GCM usage limits ovpn: limit AEAD decrypt verification failures ovpn: make direct-key AEAD layout explicit ovpn: move key slot lifecycle out of AEAD ovpn: move direct key state into key contexts ovpn: make key contexts refcounted ovpn: generalize AEAD packet ID handling ovpn: add epoch key derivation support ovpn: add epoch key slot state ovpn: handle epoch AEAD packet format ovpn: rotate epoch data keys ovpn: accept epoch keys from netlink selftests: ovpn: exercise epoch keys Documentation/netlink/specs/ovpn.yaml | 31 + drivers/net/Kconfig | 2 + drivers/net/ovpn/Makefile | 2 + drivers/net/ovpn/crypto.c | 7 +- drivers/net/ovpn/crypto.h | 125 +++- drivers/net/ovpn/crypto_aead.c | 609 +++++++++++------- drivers/net/ovpn/crypto_aead.h | 9 +- drivers/net/ovpn/crypto_epoch.c | 223 +++++++ drivers/net/ovpn/crypto_epoch.h | 58 ++ drivers/net/ovpn/crypto_key.c | 575 +++++++++++++++++ drivers/net/ovpn/crypto_limits.h | 125 ++++ drivers/net/ovpn/io.c | 246 ++++++- drivers/net/ovpn/io.h | 8 +- drivers/net/ovpn/main.c | 15 +- drivers/net/ovpn/netlink-gen.c | 9 +- drivers/net/ovpn/netlink-gen.h | 3 +- drivers/net/ovpn/netlink.c | 111 +++- drivers/net/ovpn/pktid.c | 13 +- drivers/net/ovpn/pktid.h | 164 ++++- drivers/net/ovpn/proto.h | 38 ++ drivers/net/ovpn/skb.h | 2 + include/uapi/linux/ovpn.h | 11 + tools/testing/selftests/net/ovpn/Makefile | 2 + tools/testing/selftests/net/ovpn/common.sh | 30 +- tools/testing/selftests/net/ovpn/ovpn-cli.c | 116 +++- .../selftests/net/ovpn/test-epoch-tcp.sh | 11 + .../testing/selftests/net/ovpn/test-epoch.sh | 10 + tools/testing/selftests/net/ovpn/test-mark.sh | 3 +- tools/testing/selftests/net/ovpn/test.sh | 12 +- 29 files changed, 2241 insertions(+), 329 deletions(-) create mode 100644 drivers/net/ovpn/crypto_epoch.c create mode 100644 drivers/net/ovpn/crypto_epoch.h create mode 100644 drivers/net/ovpn/crypto_key.c create mode 100644 drivers/net/ovpn/crypto_limits.h create mode 100755 tools/testing/selftests/net/ovpn/test-epoch-tcp.sh create mode 100755 tools/testing/selftests/net/ovpn/test-epoch.sh base-commit: 903db046d5579bef0ea699eae4b279dd6455fc9f