Your message dated Sat, 29 Jun 2024 10:46:16 +0000
with message-id <e1snvay-002bzt...@coccia.debian.org>
and subject line Released with 12.6
has caused the Debian Bug report #1064551,
regarding bookworm-pu: libjwt/1.10.2-1+deb12u1
to be marked as done.
This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.
(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)
--
1064551: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1064551
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian....@packages.debian.org
Usertags: pu
The attached debdiff for libjwt fixes CVE-2024-25189 in Bookworm. 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-19 22:03:02.000000000 +0100
@@ -1,3 +1,10 @@
+libjwt (1.10.2-1+deb12u1) bookworm; urgency=medium
+
+ * CVE-2024-25189 (Closes: #1063534)
+ fix a timing side channel via strcmp()
+
+ -- Thorsten Alteholz <deb...@alteholz.de> Mon, 19 Feb 2024 22: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-19 22: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-19 22: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-19
22: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-19
22: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-19 22:03:02.000000000 +0100
@@ -1,4 +1,6 @@
use-b64.patch
+CVE-2024-25189-1.patch
+CVE-2024-25189-2.patch
# do not add patches below
zzz-gnutls-soname.patch
--- End Message ---
--- Begin Message ---
Version: 12.6
The upload requested in this bug has been released as part of 12.6.
--- End Message ---