Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian....@packages.debian.org
Usertags: pu


The attached debdiff for libjwt fixes CVE-2024-25189 in Bullseye. It is marked as no-dsa by the security team.
The fix is straightfoward and should not make any problems.

  Thorsten
diff -Nru libjwt-1.10.2/debian/changelog libjwt-1.10.2/debian/changelog
--- libjwt-1.10.2/debian/changelog      2019-07-14 19:03:00.000000000 +0200
+++ libjwt-1.10.2/debian/changelog      2024-02-20 23:03:02.000000000 +0100
@@ -1,3 +1,10 @@
+libjwt (1.10.2-1+deb11u1) bullseye; urgency=medium
+
+  * CVE-2024-25189 (Closes: #1063534)
+    fix a timing side channel via strcmp()
+
+ -- Thorsten Alteholz <deb...@alteholz.de>  Tue, 20 Feb 2024 23:03:02 +0100
+
 libjwt (1.10.2-1) unstable; urgency=medium
 
   * New upstream release
diff -Nru libjwt-1.10.2/debian/libjwt0.symbols 
libjwt-1.10.2/debian/libjwt0.symbols
--- libjwt-1.10.2/debian/libjwt0.symbols        2019-01-13 15:13:51.000000000 
+0100
+++ libjwt-1.10.2/debian/libjwt0.symbols        2024-02-20 23:03:02.000000000 
+0100
@@ -38,5 +38,6 @@
  jwt_sign_sha_hmac@Base 1.9.0
  jwt_sign_sha_pem@Base 1.9.0
  jwt_str_alg@Base 1.9.0
+ jwt_strcmp@Base 1.10.2
  jwt_verify_sha_hmac@Base 1.9.0
  jwt_verify_sha_pem@Base 1.9.0
diff -Nru libjwt-1.10.2/debian/libjwt-gnutls0.symbols 
libjwt-1.10.2/debian/libjwt-gnutls0.symbols
--- libjwt-1.10.2/debian/libjwt-gnutls0.symbols 2019-01-13 15:13:51.000000000 
+0100
+++ libjwt-1.10.2/debian/libjwt-gnutls0.symbols 2024-02-20 23:03:02.000000000 
+0100
@@ -38,5 +38,6 @@
  jwt_sign_sha_hmac@Base 1.9.0
  jwt_sign_sha_pem@Base 1.9.0
  jwt_str_alg@Base 1.9.0
+ jwt_strcmp@Base 1.10.2
  jwt_verify_sha_hmac@Base 1.9.0
  jwt_verify_sha_pem@Base 1.9.0
diff -Nru libjwt-1.10.2/debian/patches/CVE-2024-25189-1.patch 
libjwt-1.10.2/debian/patches/CVE-2024-25189-1.patch
--- libjwt-1.10.2/debian/patches/CVE-2024-25189-1.patch 1970-01-01 
01:00:00.000000000 +0100
+++ libjwt-1.10.2/debian/patches/CVE-2024-25189-1.patch 2024-02-20 
23:03:02.000000000 +0100
@@ -0,0 +1,130 @@
+commit f73bac57c5bece16ac24f1a70022aa34355fc1bf
+Author: Ben Collins <bcoll...@maclara-llc.com>
+Date:   Fri Feb 9 09:03:35 2024 -0500
+
+    Implement a safer strcmp() function
+    
+    As noted, the strcmp() function can be used for time-based side attacks.
+    
+    I tried to test this and could not find a reasonable way to implement
+    this attack for several reasons:
+    
+    1) strcmp() is optimized to compare 4 and 8 bytes at a time when possible
+       on almost every modern system, making the attack almost impossible.
+    2) Running 128 million iterations of strcmp() for a single byte attack
+       gave sub-nanosecond average differences (locally on same excution stack)
+       and almost as often as the comparison was correct, it was also wrong in
+       the reverse sense (i.e. two byte strcmp() took less time than single
+       byte).
+    3) Adding noise from network, application stack, web server, etc. would
+       only add to the failure rate of guessing the differences above.
+    
+    Erwan noted that there are proofs out there showing that signal noise
+    reduction can make this guessing more "accurate", but this proof also
+    noted it would take up to 4 billion guesses to completely cover this
+    attack surface. The claim was that 50k attempts per second would break
+    a 256-bit hmac in 22 hours. While this isn't impossible, it's very
+    implausible.
+    
+    However, for the sake of cryptographic correctness, I implemented
+    jwt_strcmp() which always compares all bytes, and does so up to the
+    longest string in the 2-string set, without passing string boundaries.
+    
+    This makes it time-consistent for len(max(a,b)) comparisons. I proofed
+    this using a 128 million interation average for various scenarious.
+    
+    Reported-by: Erwan Legrand <m...@erwanlegrand.com>
+    Signed-off-by: Ben Collins <bcoll...@maclara-llc.com>
+
+Index: libjwt-1.10.2/libjwt/jwt-gnutls.c
+===================================================================
+--- libjwt-1.10.2.orig/libjwt/jwt-gnutls.c     2024-02-19 22:38:58.575655983 
+0100
++++ libjwt-1.10.2/libjwt/jwt-gnutls.c  2024-02-19 22:38:58.571655984 +0100
+@@ -90,7 +90,7 @@
+               jwt_Base64encode(buf, sig_check, len);
+               jwt_base64uri_encode(buf);
+ 
+-              if (!strcmp(sig, buf))
++              if (!jwt_strcmp(sig, buf))
+                       ret = 0;
+ 
+               free(sig_check);
+Index: libjwt-1.10.2/libjwt/jwt-openssl.c
+===================================================================
+--- libjwt-1.10.2.orig/libjwt/jwt-openssl.c    2024-02-19 22:38:58.575655983 
+0100
++++ libjwt-1.10.2/libjwt/jwt-openssl.c 2024-02-19 22:38:58.571655984 +0100
+@@ -140,7 +140,7 @@
+       jwt_base64uri_encode(buf);
+ 
+       /* And now... */
+-      ret = strcmp(buf, sig) ? EINVAL : 0;
++      ret = jwt_strcmp(buf, sig) ? EINVAL : 0;
+ 
+ jwt_verify_hmac_done:
+       BIO_free_all(b64);
+Index: libjwt-1.10.2/libjwt/jwt-private.h
+===================================================================
+--- libjwt-1.10.2.orig/libjwt/jwt-private.h    2024-02-19 22:38:58.575655983 
+0100
++++ libjwt-1.10.2/libjwt/jwt-private.h 2024-02-19 22:41:41.667637551 +0100
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 2015-2017 Ben Collins <b...@cyphre.com>
++/* Copyright (C) 2015-2024 Ben Collins <b...@cyphre.com>
+    This file is part of the JWT C Library
+ 
+    This Source Code Form is subject to the terms of the Mozilla Public
+@@ -36,4 +36,7 @@
+ 
+ int jwt_verify_sha_pem(jwt_t *jwt, const char *head, const char *sig_b64);
+ 
++/* A time-safe strcmp function */
++int jwt_strcmp(const char *str1, const char *str2);
++
+ #endif /* JWT_PRIVATE_H */
+Index: libjwt-1.10.2/libjwt/jwt.c
+===================================================================
+--- libjwt-1.10.2.orig/libjwt/jwt.c    2024-02-19 22:38:58.575655983 +0100
++++ libjwt-1.10.2/libjwt/jwt.c 2024-02-19 22:44:53.223612621 +0100
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 2015-2018 Ben Collins <b...@cyphre.com>
++/* Copyright (C) 2015-2024 Ben Collins <b...@cyphre.com>
+    This file is part of the JWT C Library
+ 
+    This Source Code Form is subject to the terms of the Mozilla Public
+@@ -16,6 +16,37 @@
+ #include "jwt-private.h"
+ #include "config.h"
+ 
++/* A time-safe strcmp function */
++int jwt_strcmp(const char *str1, const char *str2)
++{
++       /* Get the LONGEST length */
++       int len1 = strlen(str1);
++       int len2 = strlen(str2);
++       int len_max = len1 >= len2 ? len1 : len2;
++
++       int i, ret = 0;
++
++       /* Iterate the entire longest string no matter what. Only testing
++        * the shortest string would still allow attacks for
++        * "a" == "aKJSDHkjashaaHJASJ", adding a character each time one
++        * is found. */
++       for (i = 0; i < len_max; i++) {
++               char c1, c2;
++
++               c1 = len1 < i ? str1[i] : '\0';
++               c2 = len2 < i ? str2[i] : '\0';
++
++               if (c1 != c2)
++                       ret = 1;
++       }
++
++       /* Don't forget to check length */
++       if (len1 != len2)
++               ret = -1;
++
++       return ret;
++}
++
+ int jwt_Base64encode(char *coded_dst, const char *plain_src, int 
len_plain_src)
+ {
+   base64_encodestate _state;
diff -Nru libjwt-1.10.2/debian/patches/CVE-2024-25189-2.patch 
libjwt-1.10.2/debian/patches/CVE-2024-25189-2.patch
--- libjwt-1.10.2/debian/patches/CVE-2024-25189-2.patch 1970-01-01 
01:00:00.000000000 +0100
+++ libjwt-1.10.2/debian/patches/CVE-2024-25189-2.patch 2024-02-20 
23:03:02.000000000 +0100
@@ -0,0 +1,33 @@
+commit a5d61ef4f1b383876e0a78534383f38159471fd6
+Author: Ben Collins <bcoll...@maclara-llc.com>
+Date:   Fri Feb 9 09:50:34 2024 -0500
+
+    Rework jwt_strcmp() to use less branching
+    
+    Signed-off-by: Ben Collins <bcoll...@maclara-llc.com>
+
+Index: libjwt-1.10.2/libjwt/jwt.c
+===================================================================
+--- libjwt-1.10.2.orig/libjwt/jwt.c    2024-02-19 22:45:21.051608706 +0100
++++ libjwt-1.10.2/libjwt/jwt.c 2024-02-19 22:48:04.203584376 +0100
+@@ -33,16 +33,14 @@
+        for (i = 0; i < len_max; i++) {
+                char c1, c2;
+ 
+-               c1 = len1 < i ? str1[i] : '\0';
+-               c2 = len2 < i ? str2[i] : '\0';
++               c1 = (i < len1) ? str1[i] : 0;
++               c2 = (i < len2) ? str2[i] : 0;
+ 
+-               if (c1 != c2)
+-                       ret = 1;
++               ret |= c1 ^ c2;
+        }
+ 
+        /* Don't forget to check length */
+-       if (len1 != len2)
+-               ret = -1;
++       ret |= len1 ^ len2;
+ 
+        return ret;
+ }
diff -Nru libjwt-1.10.2/debian/patches/series 
libjwt-1.10.2/debian/patches/series
--- libjwt-1.10.2/debian/patches/series 2019-01-13 15:13:51.000000000 +0100
+++ libjwt-1.10.2/debian/patches/series 2024-02-20 23:03:02.000000000 +0100
@@ -1,4 +1,7 @@
 use-b64.patch
 
+CVE-2024-25189-1.patch
+CVE-2024-25189-2.patch
+
 # do not add patches below
 zzz-gnutls-soname.patch

Reply via email to