Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package mbedtls-2 for openSUSE:Factory 
checked in at 2026-09-15 12:49:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mbedtls-2 (Old)
 and      /work/SRC/openSUSE:Factory/.mbedtls-2.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mbedtls-2"

Tue Sep 15 12:49:00 2026 rev:13 rq:1378063 version:2.28.10

Changes:
--------
--- /work/SRC/openSUSE:Factory/mbedtls-2/mbedtls-2.changes      2026-06-22 
17:33:45.938840371 +0200
+++ /work/SRC/openSUSE:Factory/.mbedtls-2.new.383539/mbedtls-2.changes  
2026-09-15 12:49:13.755955854 +0200
@@ -1,0 +2,15 @@
+Tue Sep 15 05:00:15 UTC 2026 - Martin Pluskal <[email protected]>
+
+- CVE-2025-52496: race condition in AESNI support detection, AES key
+  disclosure / GCM forgery in multithreaded programs (boo#1245810)
+  * Add mbedtls-fix-CVE-2025-52496.patch: backport upstream fix
+
+-------------------------------------------------------------------
+Mon Sep 14 17:22:23 UTC 2026 - Martin Pluskal <[email protected]>
+
+- CVE-2025-59438: padding oracle through timing of cipher error
+  reporting (boo#1252454)
+  * Add mbedtls-fix-CVE-2025-59438.patch: backport upstream 3.6 fix
+- Spec cleanup (spec-cleaner): drop obsolete Group tags
+
+-------------------------------------------------------------------

New:
----
  mbedtls-fix-CVE-2025-52496.patch
  mbedtls-fix-CVE-2025-59438.patch

----------(New B)----------
  New:  disclosure / GCM forgery in multithreaded programs (boo#1245810)
  * Add mbedtls-fix-CVE-2025-52496.patch: backport upstream fix
  New:  reporting (boo#1252454)
  * Add mbedtls-fix-CVE-2025-59438.patch: backport upstream 3.6 fix
- Spec cleanup (spec-cleaner): drop obsolete Group tags
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mbedtls-2.spec ++++++
--- /var/tmp/diff_new_pack.YSYhPP/_old  2026-09-15 12:49:14.661993624 +0200
+++ /var/tmp/diff_new_pack.YSYhPP/_new  2026-09-15 12:49:14.663993707 +0200
@@ -25,18 +25,21 @@
 Release:        0
 Summary:        Libraries for crypto and SSL/TLS protocols
 License:        Apache-2.0 OR GPL-2.0-or-later
-Group:          Development/Libraries/C and C++
 URL:            https://tls.mbed.org
 Source:         
https://github.com/ARMmbed/mbedtls/archive/v%{version}.tar.gz#/%{_rname}-%{version}.tar.gz
 Source99:       baselibs.conf
+# PATCH-FIX-UPSTREAM: Fix build with gcc15
+Patch0:         mbedtls-fix-build-with-gcc-15.patch
+# PATCH-FIX-UPSTREAM: mbedtls-fix-CVE-2025-59438.patch boo#1252454 -- fix 
padding oracle through timing of cipher error reporting (CVE-2025-59438, 
upstream 3.6 commits 155de2ab/d179dc80/e74b4283/3b380dae/04dfd704/cc908ad0)
+Patch1:         mbedtls-fix-CVE-2025-59438.patch
+# PATCH-FIX-UPSTREAM: mbedtls-fix-CVE-2025-52496.patch boo#1245810 -- fix race 
condition in AESNI support detection (CVE-2025-52496, upstream commit 8c67ac0f)
+Patch2:         mbedtls-fix-CVE-2025-52496.patch
 BuildRequires:  cmake
 BuildRequires:  ninja
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(libpkcs11-helper-1)
 BuildRequires:  pkgconfig(zlib)
 %{?suse_build_hwcaps_libs}
-# PATCH-FIX-UPSTREAM: Fix build with gcc15
-Patch0:         mbedtls-fix-build-with-gcc-15.patch
 
 %description
 mbedtls implements the SSL3, TLS 1.0, 1.1 and 1.2 protocols. It
@@ -49,7 +52,6 @@
 
 %package -n %{lib_tls}
 Summary:        Transport Layer Security protocol suite
-Group:          System/Libraries
 
 %description -n %{lib_tls}
 mbedtls implements the SSL 3.0, TLS 1.0, 1.1 and 1.2 protocols. It
@@ -62,7 +64,6 @@
 
 %package -n %{lib_crypto}
 Summary:        Cryptographic base library for mbedtls
-Group:          System/Libraries
 
 %description -n %{lib_crypto}
 This subpackage of mbedtls contains a library that exposes
@@ -71,7 +72,6 @@
 
 %package -n %{lib_x509}
 Summary:        Library to work with X.509 certificates
-Group:          System/Libraries
 
 %description -n %{lib_x509}
 This subpackage of mbedtls contains a library that can read, verify
@@ -80,7 +80,6 @@
 
 %package devel
 Summary:        Development files for mbedtls, a SSL/TLS library
-Group:          Development/Libraries/C and C++
 Requires:       %{lib_crypto} = %{version}
 Requires:       %{lib_tls} = %{version}
 Requires:       %{lib_x509} = %{version}

++++++ mbedtls-fix-CVE-2025-52496.patch ++++++
Subject: Fix race condition in AESNI support detection (CVE-2025-52496)
Patch-mainline: Backport of upstream commit 
8c67ac0f7f8863e60714f16513b4d420c764c093
References:
 
https://github.com/Mbed-TLS/mbedtls/commit/8c67ac0f7f8863e60714f16513b4d420c764c093
 https://github.com/Mbed-TLS/mbedtls/issues/9840

Backport the upstream fix for CVE-2025-52496 (boo#1245810) to 2.28.
mbedtls_aesni_has_support() cached the CPUID result in plain static
variables, allowing the compiler to hoist `done = 1` above the store
to `c`. Two threads racing at startup could then observe `done == 1`
with `c == 0` and fall back to software AES even though AESNI is
available, opening timing attacks (AES key disclosure / GCM forgery
in multithreaded programs). Mark both statics volatile with the
upstream comment so the stores are not reordered.

CVE-2025-52496 boo#1245810

---
diff --git a/library/aesni.c b/library/aesni.c
--- a/library/aesni.c
+++ b/library/aesni.c
@@ -42,8 +42,12 @@
  */
 int mbedtls_aesni_has_support(unsigned int what)
 {
-    static int done = 0;
-    static unsigned int c = 0;
+    /* To avoid a race condition, tell the compiler that the assignment
+     * `done = 1` and the assignment to `c` may not be reordered.
+     * https://github.com/Mbed-TLS/mbedtls/issues/9840
+     */
+    static volatile int done = 0;
+    static volatile unsigned int c = 0;
 
     if (!done) {
 #if MBEDTLS_AESNI_HAVE_CODE == 2

++++++ mbedtls-fix-CVE-2025-59438.patch ++++++
Subject: Fix padding oracle through timing of cipher error reporting 
(CVE-2025-59438)
Patch-mainline: Backport of upstream 3.6 fix
References:
 
https://github.com/Mbed-TLS/mbedtls/commit/155de2ab775e77ab6fa81bf2b1e6e63768123bc1
 
https://github.com/Mbed-TLS/mbedtls/commit/d179dc80a5b13189c79fe4531eacb28698a7a0e9
 
https://github.com/Mbed-TLS/mbedtls/commit/e74b42832e4af11606ef8aae2c9404b4acaa2c6d
 
https://github.com/Mbed-TLS/mbedtls/commit/3b380daedbce9fae3e7ed7e84f18e97876e7e6f3
 
https://github.com/Mbed-TLS/mbedtls/commit/04dfd704325a6dbc2a13eb7f418eaca9ae9ca549
 
https://github.com/Mbed-TLS/mbedtls/commit/cc908ad04c388b50b81fa3b3a8b509cf62797fcf

Backport the 3.6.x fix for CVE-2025-59438 (boo#1252454) to the 2.28
code base. Decryption with CBC-PKCS7 leaked the presence of padding
errors through timing: mbedtls_psa_cipher_finish() translated
mbedtls_cipher_finish() errors via mbedtls_to_psa_error(), and the
callers branched on status and on the output length.

Add mbedtls_cipher_finish_padded(), which reports invalid padding
through a separate all-bits-one mask instead of an error code, use it
in mbedtls_psa_cipher_finish(), copy a fixed amount and derive the
PSA status (INVALID_PADDING vs BUFFER_TOO_SMALL) without branching on
the sensitive values, and make psa_cipher_finish(),
psa_cipher_decrypt() and mbedtls_psa_cipher_decrypt() avoid code paths
that depend on the sensitive status/output length.

2.28 lacks the mbedtls_ct_condition_t framework the 3.6 fix uses, so
the same operations are implemented here with plain branch-free
size_t arithmetic (masks are 0 or all-bits-one).

CVE-2025-59438 boo#1252454

---
diff -u -r a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
--- a/include/mbedtls/cipher.h  2025-03-21 00:13:48.000000000 +0100
+++ b/include/mbedtls/cipher.h  2026-09-14 19:20:01.938914513 +0200
@@ -714,7 +714,7 @@
  *                1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce.
  *                2. mbedtls_cipher_reset()
  *                3. mbedtls_cipher_update() one or more times
- *                4. mbedtls_cipher_finish()
+ *                4. mbedtls_cipher_finish() or mbedtls_cipher_finish_padded()
  *                .
  *                This sequence can be repeated to encrypt or decrypt multiple
  *                messages with the same key.
@@ -764,7 +764,8 @@
  *                      many block-sized blocks of data as possible to output.
  *                      Any data that cannot be written immediately is either
  *                      added to the next block, or flushed when
- *                      mbedtls_cipher_finish() is called.
+ *                      mbedtls_cipher_finish() or 
mbedtls_cipher_finish_padded()
+ *                      is called.
  *                      Exception: For MBEDTLS_MODE_ECB, expects a single block
  *                      in size. For example, 16 Bytes for AES.
  *
@@ -803,6 +804,19 @@
  *                      contained in it is padded to the size of
  *                      the last block, and written to the \p output buffer.
  *
+ * \warning             This function reports invalid padding through an error
+ *                      code. Adversaries may be able to decrypt encrypted
+ *                      data if they can submit chosen ciphertexts and
+ *                      detect whether it has valid padding or not,
+ *                      either through direct observation or through a side
+ *                      channel such as timing. This is known as a
+ *                      padding oracle attack.
+ *                      Therefore applications that call this function for
+ *                      decryption with a cipher that involves padding
+ *                      should take care around error handling. Preferably,
+ *                      such applications should use
+ *                      mbedtls_cipher_finish_padded() instead of this 
function.
+ *
  * \param ctx           The generic cipher context. This must be initialized 
and
  *                      bound to a key.
  * \param output        The buffer to write data to. This needs to be a 
writable
@@ -816,12 +830,56 @@
  * \return              #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
  *                      expecting a full block but not receiving one.
  * \return              #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
- *                      while decrypting.
+ *                      while decrypting. Note that invalid-padding errors
+ *                      should be handled carefully; see the warning above.
  * \return              A cipher-specific error code on failure.
  */
 int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
                           unsigned char *output, size_t *olen);
 
+/**
+ * \brief               The generic cipher finalization function. If data still
+ *                      needs to be flushed from an incomplete block, the data
+ *                      contained in it is padded to the size of
+ *                      the last block, and written to the \p output buffer.
+ *
+ * \note                This function is similar to mbedtls_cipher_finish().
+ *                      The only difference is that it reports invalid padding
+ *                      on decryption differently, through the \p 
invalid_padding
+ *                      parameter rather than an error code.
+ *                      For encryption, and in modes without padding (including
+ *                      all authenticated modes), this function is identical
+ *                      to mbedtls_cipher_finish().
+ *
+ * \param ctx           The generic cipher context. This must be initialized 
and
+ *                      bound to a key.
+ * \param output        The buffer to write data to. This needs to be a 
writable
+ *                      buffer of at least block_size Bytes.
+ * \param olen          The length of the data written to the \p output buffer.
+ *                      This may not be \c NULL.
+ * \param invalid_padding
+ *                      If this function returns \c 0 on decryption,
+ *                      \p *invalid_padding is \c 0 if the ciphertext was
+ *                      valid, and all-bits-one if the ciphertext had invalid
+ *                      padding.
+ *                      On encryption, or in a mode without padding (including
+ *                      all authenticated modes), \p *invalid_padding is \c 0
+ *                      on success.
+ *                      The value in \p *invalid_padding is unspecified if
+ *                      this function returns a nonzero status.
+ *
+ * \return              \c 0 on success.
+ *                      Also \c 0 for decryption with invalid padding.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ *                      expecting a full block but not receiving one.
+ * \return              A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx,
+                                 unsigned char *output, size_t *olen,
+                                 size_t *invalid_padding);
+
 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
 /**
  * \brief               This function writes a tag for AEAD ciphers.
diff -u -r a/library/cipher.c b/library/cipher.c
--- a/library/cipher.c  2025-03-21 00:13:48.000000000 +0100
+++ b/library/cipher.c  2026-09-14 19:20:19.400877063 +0200
@@ -992,6 +992,23 @@
     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
 }
 
+int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx,
+                                 unsigned char *output, size_t *olen,
+                                 size_t *invalid_padding)
+{
+    *invalid_padding = 0;
+    int ret = mbedtls_cipher_finish(ctx, output, olen);
+#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) || \
+    defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) || \
+    defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
+    if (ret == MBEDTLS_ERR_CIPHER_INVALID_PADDING) {
+        ret = 0;
+        *invalid_padding = SIZE_MAX;
+    }
+#endif
+    return ret;
+}
+
 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
 int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
                                     mbedtls_cipher_padding_t mode)
diff -u -r a/library/psa_crypto.c b/library/psa_crypto.c
--- a/library/psa_crypto.c      2025-03-21 00:13:48.000000000 +0100
+++ b/library/psa_crypto.c      2026-09-14 19:21:39.017825212 +0200
@@ -217,6 +217,15 @@
     output_copy = NULL;
 #endif /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */
 
+/* Branch-free mask for CVE-2025-59438 (padding oracle through timing of
+ * cipher error reporting). Returns SIZE_MAX if x != 0, 0 otherwise, without
+ * branching on x, so that callers can clear *output_length on failure
+ * without leaking whether the failure was PSA_ERROR_INVALID_PADDING. */
+static size_t psa_ct_mask_nonzero(size_t x)
+{
+    return (size_t) (0 - (((x | (size_t) (0 - x)) >> (sizeof(size_t) * 8 - 1)) 
& 1u));
+}
+
 psa_status_t mbedtls_to_psa_error(int ret)
 {
     /* Mbed TLS error codes can combine a high-level error code and a
@@ -3957,12 +3966,24 @@
                                               output_length);
 
 exit:
-    if (status == PSA_SUCCESS) {
-        status = psa_cipher_abort(operation);
-    } else {
-        *output_length = 0;
-        (void) psa_cipher_abort(operation);
-    }
+    /* C99 doesn't allow a declaration to follow a label */;
+    psa_status_t abort_status = psa_cipher_abort(operation);
+    /* Normally abort shouldn't fail unless the operation is in a bad
+     * state, in which case we'd expect finish to fail with the same error.
+     * So it doesn't matter much which call's error code we pick when both
+     * fail. However, in unauthenticated decryption specifically, the
+     * distinction between PSA_SUCCESS and PSA_ERROR_INVALID_PADDING is
+     * security-sensitive (risk of a padding oracle attack), so here we
+     * must not have a code path that depends on the value of status. */
+    if (abort_status != PSA_SUCCESS) {
+        status = abort_status;
+    }
+
+    /* Set *output_length to 0 if status != PSA_SUCCESS, without
+     * leaking the value of status through a timing side channel
+     * (status == PSA_ERROR_INVALID_PADDING is sensitive when doing
+     * decryption with unpadding, due to the risk of padding oracle attack). */
+    *output_length &= ~psa_ct_mask_nonzero((size_t) status);
 
     LOCAL_OUTPUT_FREE(output_external, output);
 
@@ -4116,13 +4137,15 @@
 
 exit:
     unlock_status = psa_unlock_key_slot(slot);
-    if (status == PSA_SUCCESS) {
+    if (unlock_status != PSA_SUCCESS) {
         status = unlock_status;
     }
 
-    if (status != PSA_SUCCESS) {
-        *output_length = 0;
-    }
+    /* Set *output_length to 0 if status != PSA_SUCCESS, without
+     * leaking the value of status through a timing side channel
+     * (status == PSA_ERROR_INVALID_PADDING is sensitive when doing
+     * decryption with unpadding, due to the risk of padding oracle attack). */
+    *output_length &= ~psa_ct_mask_nonzero((size_t) status);
 
     LOCAL_INPUT_FREE(input_external, input);
     LOCAL_OUTPUT_FREE(output_external, output);
diff -u -r a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
--- a/library/psa_crypto_cipher.c       2025-03-21 00:13:48.000000000 +0100
+++ b/library/psa_crypto_cipher.c       2026-09-14 19:24:24.848462917 +0200
@@ -149,6 +149,31 @@
 
 #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
 
+/* Constant-time helpers for CVE-2025-59438 (padding oracle through timing
+ * of cipher error reporting).
+ *
+ * 2.28 lacks the mbedtls_ct_condition_t framework introduced for this fix
+ * in 3.6, so implement the same operations with plain branch-free size_t
+ * arithmetic. Masks are 0 or SIZE_MAX (all-bits-one); all helpers avoid
+ * data-dependent branches and memory accesses.
+ */
+static size_t psa_ct_mask_lt(size_t x, size_t y)
+{
+    const size_t msb_diff = ((x ^ y) >> (sizeof(size_t) * 8 - 1)) & 1u;
+    const size_t mask_msb_diff = (size_t) (0 - msb_diff);
+    const size_t diff = x - y;
+    const size_t sel = (mask_msb_diff & y) | (~mask_msb_diff & diff);
+    return (size_t) (0 - ((sel >> (sizeof(size_t) * 8 - 1)) & 1u));
+}
+
+static psa_status_t psa_ct_error_if(size_t cond, psa_status_t if1, 
psa_status_t if0)
+{
+    size_t u1 = (size_t) (0 - (int) if1);
+    size_t u0 = (size_t) (0 - (int) if0);
+    size_t sel = (cond & u1) | (~cond & u0);
+    return (psa_status_t) (0 - sel);
+}
+
 static psa_status_t psa_cipher_setup(
     mbedtls_psa_cipher_operation_t *operation,
     const psa_key_attributes_t *attributes,
@@ -424,7 +449,19 @@
     uint8_t *output, size_t output_size, size_t *output_length)
 {
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
-    uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
+    size_t invalid_padding = 0;
+
+    /* We will copy output_size bytes from temp_output_buffer to the
+     * output buffer. We can't use *output_length to determine how
+     * much to copy because we must not leak that value through timing
+     * when doing decryption with unpadding. But the underlying function
+     * is not guaranteed to write beyond *output_length. To ensure we don't
+     * leak the former content of the stack to the caller, wipe that
+     * former content. */
+    uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH] = { 0 };
+    if (output_size > sizeof(temp_output_buffer)) {
+        output_size = sizeof(temp_output_buffer);
+    }
 
     if (operation->ctx.cipher.unprocessed_len != 0) {
         if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
@@ -435,21 +472,28 @@
     }
 
     status = mbedtls_to_psa_error(
-        mbedtls_cipher_finish(&operation->ctx.cipher,
-                              temp_output_buffer,
-                              output_length));
+        mbedtls_cipher_finish_padded(&operation->ctx.cipher,
+                                     temp_output_buffer,
+                                     output_length,
+                                     &invalid_padding));
     if (status != PSA_SUCCESS) {
         goto exit;
     }
 
-    if (*output_length == 0) {
+    if (output_size == 0) {
         ; /* Nothing to copy. Note that output may be NULL in this case. */
-    } else if (output_size >= *output_length) {
-        memcpy(output, temp_output_buffer, *output_length);
     } else {
-        status = PSA_ERROR_BUFFER_TOO_SMALL;
+        /* Do not use the value of *output_length to determine how much
+         * to copy. When decrypting a padded cipher, the output length is
+         * sensitive, and leaking it could allow a padding oracle attack. */
+        memcpy(output, temp_output_buffer, output_size);
     }
 
+    status = psa_ct_error_if(invalid_padding,
+                             PSA_ERROR_INVALID_PADDING, PSA_SUCCESS);
+    status = psa_ct_error_if(psa_ct_mask_lt(output_size, *output_length),
+                             PSA_ERROR_BUFFER_TOO_SMALL, status);
+
 exit:
     mbedtls_platform_zeroize(temp_output_buffer,
                              sizeof(temp_output_buffer));
@@ -579,10 +623,17 @@
     *output_length = accumulated_length + olength;
 
 exit:
-    if (status == PSA_SUCCESS) {
-        status = mbedtls_psa_cipher_abort(&operation);
-    } else {
-        mbedtls_psa_cipher_abort(&operation);
+    /* C99 doesn't allow a declaration to follow a label */;
+    psa_status_t abort_status = mbedtls_psa_cipher_abort(&operation);
+    /* Normally abort shouldn't fail unless the operation is in a bad
+     * state, in which case we'd expect finish to fail with the same error.
+     * So it doesn't matter much which call's error code we pick when both
+     * fail. However, in unauthenticated decryption specifically, the
+     * distinction between PSA_SUCCESS and PSA_ERROR_INVALID_PADDING is
+     * security-sensitive (risk of a padding oracle attack), so here we
+     * must not have a code path that depends on the value of status. */
+    if (abort_status != PSA_SUCCESS) {
+        status = abort_status;
     }
 
     return status;

Reply via email to