new file mode 100644
@@ -0,0 +1,130 @@
+From 6bc7dd87d543c882994f95c8309846dfda9ab503 Mon Sep 17 00:00:00 2001
+From: "djm@openbsd.org" <djm@openbsd.org>
+Date: Mon, 6 Jul 2026 07:44:48 +0000
+Subject: [PATCH] upstream: Fix cases in GSSAPI and keyboard-interactive
+
+authentication where the minimum per-attempt delay was not being enforced.
+
+Reported by Orange Cyberdefense Vulnerability Team
+
+OpenBSD-Commit-ID: c40bd35cc2428fcaccad7a141703c28baa6da01e
+
+CVE: CVE-2026-60001
+Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/d43ba60c91cb323ca921049b7d43b1908c318454]
+
+Backport Changes:
+- Omitted the upstream OpenBSD revision-only hunks in auth.h,
+ auth2-chall.c, auth2-gss.c, and auth2.c and retained the Wrynose
+ OpenSSH 10.3p1 revisions because this stable backport carries only the
+ functional security changes.
+
+(cherry picked from commit d43ba60c91cb323ca921049b7d43b1908c318454)
+Signed-off-by: Devansh Patel <devanshp@cisco.com>
+---
+ auth.h | 1 +
+ auth2-chall.c | 4 ++++
+ auth2-gss.c | 7 +++++++
+ auth2.c | 10 ++++++++--
+ 4 files changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/auth.h b/auth.h
+index 634a84aa8..c2cfa5ed8 100644
+--- a/auth.h
++++ b/auth.h
+@@ -175,6 +175,7 @@ void auth_log(struct ssh *, int, int, const char *, const char *);
+ void auth_maxtries_exceeded(struct ssh *) __attribute__((noreturn));
+ void userauth_finish(struct ssh *, int, const char *, const char *);
+ int auth_root_allowed(struct ssh *, const char *);
++void auth_failure_delay(Authctxt *, double);
+
+ char *auth2_read_banner(void);
+ int auth2_methods_valid(const char *, int);
+diff --git a/auth2-chall.c b/auth2-chall.c
+index f3889079b..4687ca8e2 100644
+--- a/auth2-chall.c
++++ b/auth2-chall.c
+@@ -300,6 +300,7 @@ input_userauth_info_response(int type, uint32_t seq, struct ssh *ssh)
+ u_int i, nresp;
+ const char *devicename = NULL;
+ char **response = NULL;
++ double tstart = monotime_double();
+
+ if (authctxt == NULL)
+ fatal_f("no authctxt");
+@@ -358,6 +359,9 @@ input_userauth_info_response(int type, uint32_t seq, struct ssh *ssh)
+ auth2_challenge_start(ssh);
+ }
+ }
++
++ if (!authenticated)
++ auth_failure_delay(authctxt, tstart);
+ userauth_finish(ssh, authenticated, "keyboard-interactive",
+ devicename);
+ return 0;
+diff --git a/auth2-gss.c b/auth2-gss.c
+index 053548527..f27ac9221 100644
+--- a/auth2-gss.c
++++ b/auth2-gss.c
+@@ -255,6 +255,7 @@ input_gssapi_exchange_complete(int type, uint32_t plen, struct ssh *ssh)
+ {
+ Authctxt *authctxt = ssh->authctxt;
+ int r, authenticated;
++ double tstart = monotime_double();
+
+ if (authctxt == NULL)
+ fatal("No authentication or GSSAPI context");
+@@ -268,6 +269,8 @@ input_gssapi_exchange_complete(int type, uint32_t plen, struct ssh *ssh)
+ fatal_fr(r, "parse packet");
+
+ authenticated = mm_ssh_gssapi_userok(authctxt->user);
++ if (!authenticated)
++ auth_failure_delay(authctxt, tstart);
+
+ authctxt->postponed = 0;
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+@@ -288,6 +291,7 @@ input_gssapi_mic(int type, uint32_t plen, struct ssh *ssh)
+ gss_buffer_desc mic, gssbuf;
+ u_char *p;
+ size_t len;
++ double tstart = monotime_double();
+
+ if (authctxt == NULL)
+ fatal("No authentication or GSSAPI context");
+@@ -315,6 +319,9 @@ input_gssapi_mic(int type, uint32_t plen, struct ssh *ssh)
+ sshbuf_free(b);
+ free(mic.value);
+
++ if (!authenticated)
++ auth_failure_delay(authctxt, tstart);
++
+ authctxt->postponed = 0;
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+diff --git a/auth2.c b/auth2.c
+index 3a1682746..7ba611c02 100644
+--- a/auth2.c
++++ b/auth2.c
+@@ -265,6 +265,12 @@ ensure_minimum_time_since(double start, double seconds)
+ nanosleep(&ts, NULL);
+ }
+
++void
++auth_failure_delay(Authctxt *authctxt, double tstart)
++{
++ ensure_minimum_time_since(tstart, user_specific_delay(authctxt->user));
++}
++
+ static int
+ input_userauth_request(int type, uint32_t seq, struct ssh *ssh)
+ {
+@@ -346,8 +352,8 @@ input_userauth_request(int type, uint32_t seq, struct ssh *ssh)
+ authenticated = m->userauth(ssh, method);
+ }
+ if (!authctxt->authenticated && strcmp(method, "none") != 0)
+- ensure_minimum_time_since(tstart,
+- user_specific_delay(authctxt->user));
++ auth_failure_delay(authctxt, tstart);
++
+ userauth_finish(ssh, authenticated, method, NULL);
+ r = 0;
+ out:
@@ -29,6 +29,7 @@ SRC_URI = "https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.ta
file://CVE-2026-59998.patch \
file://CVE-2026-59996.patch \
file://CVE-2026-59995.patch \
+ file://CVE-2026-60001.patch \
"
SRC_URI[sha256sum] = "56682a36bb92dcf4b4f016fd8ec8e74059b79a8de25c15d670d731e7d18e45f4"