[Openvpn-devel,v5] Add --debug-aead-usage-limit-override option

Message ID 20261017163328.12832-1-gert@greenie.muc.de
State New
Headers
Series [Openvpn-devel,v5] Add --debug-aead-usage-limit-override option |

Commit Message

Gert Doering Oct. 17, 2026, 4:33 p.m. UTC
  From: Arne Schwabe <arne@rfc2549.org>

Normal users should not touch this option since there is normally
no reason to mess with the number of safely encrypted packets.

However, during to check if the epoch key rollover works as expected
it is helpful to trigger this mechanism early. Since constantly
patching OpenVPN to do this in tests is messy, introduce an undocumented
option to allow enabling this behaviour.

Change-Id: Iecffd01567376960c9393770ffe05665073b067a
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Antonio Quartulli <antonio@mandelbit.com>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1941
---

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/+/1941
This mail reflects revision 5 of this Change.

Acked-by according to Gerrit (reflected above):
Antonio Quartulli <antonio@mandelbit.com>
  

Patch

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 3c2ebf9..06effe2 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -3286,6 +3286,7 @@ 
     to.packet_timeout = options->tls_timeout;
     to.renegotiate_bytes = options->renegotiate_bytes;
     to.renegotiate_packets = options->renegotiate_packets;
+    to.aead_usage_limit_override = options->aead_usage_limit_override;
     if (options->renegotiate_seconds_min < 0)
     {
         /* Add 10% jitter to reneg-sec by default (server side only) */
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 7fc8614..1630731 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -7609,6 +7609,20 @@ 
             options->renegotiate_seconds_min = positive_atoi(p[2], msglevel);
         }
     }
+#ifdef ENABLE_DEBUG
+    else if (streq(p[0], "debug-aead-usage-limit-override"))
+    {
+        /* This option is undocumented since it should not be used by normal
+         * users */
+        VERIFY_PERMISSION(OPT_P_TLS_PARMS);
+        if (!positive_atoll(p[1], &options->aead_usage_limit_override, p[0], msglevel))
+        {
+            msg(M_VERB0, "Warning: --debug-aead-usage-limit-override should "
+                         "only be used by developers and in specific tests.");
+            goto err;
+        }
+    }
+#endif
     else if (streq(p[0], "hand-window") && p[1] && !p[2])
     {
         VERIFY_PERMISSION(OPT_P_TLS_PARMS);
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index d347830..693d9cf 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -647,6 +647,9 @@ 
     int renegotiate_seconds;
     int renegotiate_seconds_min;
 
+    /** Debug override to trigger AEAD usage limit early */
+    int64_t aead_usage_limit_override;
+
     /* Data channel key handshake must finalize
      * within n seconds of handshake initiation. */
     int handshake_window;
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 3594871..3fd52f0 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -126,11 +126,11 @@ 
 }
 
 static uint64_t
-tls_get_limit_aead(const char *ciphername)
+tls_get_limit_aead(const char *ciphername, uint64_t override)
 {
     uint64_t limit = cipher_get_aead_limits(ciphername);
 
-    if (limit == 0)
+    if (limit == 0 && override == 0)
     {
         return 0;
     }
@@ -139,6 +139,11 @@ 
      * we go over the limit */
     limit = limit / 8 * 7;
 
+    if (override > 0)
+    {
+        limit = override;
+    }
+
     msg(D_SHOW_KEYS,
         "Note: AEAD cipher %s will trigger a renegotiation"
         " at a sum of %" PRIi64 " blocks and packets.",
@@ -1397,6 +1402,11 @@ 
      * */
     epoch_init_key_ctx(co, key_type, &e1_send, &e1_recv, future_key_count);
 
+    if (multi->opt.aead_usage_limit_override)
+    {
+        co->aead_usage_limit = multi->opt.aead_usage_limit_override;
+    }
+
     secure_memzero(&e1_send, sizeof(e1_send));
     secure_memzero(&e1_recv, sizeof(e1_recv));
 }
@@ -1619,7 +1629,7 @@ 
     }
     tls_limit_reneg_bytes(session->opt->key_type.cipher, &session->opt->renegotiate_bytes);
 
-    session->opt->aead_usage_limit = tls_get_limit_aead(session->opt->key_type.cipher);
+    session->opt->aead_usage_limit = tls_get_limit_aead(session->opt->key_type.cipher, session->opt->aead_usage_limit_override);
 
     /* set the state of the keys for the session to generated */
     ks->state = S_GENERATED_KEYS;
diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h
index f6392f9..579f46c 100644
--- a/src/openvpn/ssl_common.h
+++ b/src/openvpn/ssl_common.h
@@ -346,6 +346,11 @@ 
     /** limit for AEAD cipher when not running in epoch data key mode,
      *  this is the sum of packets + blocks that are allowed to be used */
     uint64_t aead_usage_limit;
+    /**
+     * Debug only option that allows overriding the usage limit
+     * This allows testing key rotation by using very small limits
+     */
+    uint64_t aead_usage_limit_override;
     interval_t renegotiate_seconds;
 
     /* cert verification parms */