Commit 68c0861075 for openssl.org

commit 68c08610751e4c8495725d1d235cf75c6eef1b9c
Author: Igor Ustinov <igus@openssl.foundation>
Date:   Thu Jun 25 09:09:19 2026 +0200

    Fix a bug in BN_ucmp() when comparing constant-time BIGNUMs of different lengths

    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
    Reviewed-by: Neil Horman <nhorman@openssl.org>
    MergeDate: Fri Jul 10 12:08:43 2026
    (Merged from https://github.com/openssl/openssl/pull/31717)

diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index 161f4e10a7..a63e2b9154 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -696,19 +696,37 @@ int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
     int i;
     BN_ULONG t1, t2, *ap, *bp;

+    /*
+     * As it is a public API function, we should handle NULL parameters in
+     * some way. The function can’t return an error, so let’s define that NULL
+     * is less than any BIGNUM.
+     */
+    if (!ossl_assert(a != NULL && b != NULL))
+        return (b == NULL) - (a == NULL);
+
     ap = a->d;
     bp = b->d;

     if (BN_get_flags(a, BN_FLG_CONSTTIME)
-        && a->top == b->top) {
+        || BN_get_flags(b, BN_FLG_CONSTTIME)) {
         int res = 0;
+        int min_top = a->top < b->top ? a->top : b->top;

-        for (i = 0; i < b->top; i++) {
+        for (i = 0; i < min_top; i++) {
             res = constant_time_select_int((int)constant_time_lt_bn(ap[i], bp[i]),
                 -1, res);
             res = constant_time_select_int((int)constant_time_lt_bn(bp[i], ap[i]),
                 1, res);
         }
+
+        for (i = min_top; i < a->top; ++i)
+            res = constant_time_select_int((int)constant_time_is_zero_bn(ap[i]),
+                res, 1);
+
+        for (i = min_top; i < b->top; ++i)
+            res = constant_time_select_int((int)constant_time_is_zero_bn(bp[i]),
+                res, -1);
+
         return res;
     }