Commit 66ead9927d for openssl.org

commit 66ead9927dc7aba0dcfb9068f9288ce1e4feda53
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date:   Fri Jan 23 08:43:54 2026 +0100

    s390x: EC: use OpenSSL's RNG for ECDSA nonce 'k' for FIPS module

    The KDSA instruction can operate in 2 different modes:
    - Deterministic mode - nonce 'k' is supplied by user.
    - Non-deterministic mode - nonce 'k' is randomly generated by the instruction
      itself.

    When running in the FIPS-Module, do not use KDSA's non-deterministic mode,
    but generate the nonce 'k' using OpenSSL's random number generator. This
    ensures that the nonce is generated using a FIPS-approved random number
    generator.

    It also makes the FIPS KAT tests work, because those use a pre-setup
    deterministic random number generator to produce deterministic ECDSA
    signatures even for non-deterministic mode.

    Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>

    Reviewed-by: Tomas Mraz <tomas@openssl.org>
    Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/29754)

diff --git a/crypto/ec/ecp_s390x_nistp.c b/crypto/ec/ecp_s390x_nistp.c
index 30754d4e75..fef106e243 100644
--- a/crypto/ec/ecp_s390x_nistp.c
+++ b/crypto/ec/ecp_s390x_nistp.c
@@ -127,6 +127,8 @@ ret:
     return rc;
 }

+#define MIN_ECDSA_SIGN_ORDERBITS 64
+
 static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
     int dgstlen,
     const BIGNUM *kinv,
@@ -141,11 +143,16 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
     const EC_GROUP *group;
     const BIGNUM *privkey;
     BN_CTX *bn_ctx = NULL;
+    const BIGNUM *order;
+#ifdef FIPS_MODULE
+    int order_bits;
+#endif
     int off;

     group = EC_KEY_get0_group(eckey);
+    order = EC_GROUP_get0_order(group);
     privkey = EC_KEY_get0_private_key(eckey);
-    if (group == NULL || privkey == NULL) {
+    if (group == NULL || order == NULL || privkey == NULL) {
         ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
         return NULL;
     }
@@ -183,6 +190,42 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
             ERR_raise(ERR_LIB_EC, EC_R_INVALID_LENGTH);
             goto ret;
         }
+#ifdef FIPS_MODULE
+        /* get random value of k using OpenSSL's RNG */
+        bn_ctx = BN_CTX_secure_new_ex(ossl_ec_key_get_libctx(eckey));
+        if (bn_ctx == NULL)
+            goto ret;
+
+        /* Preallocate space */
+        order_bits = BN_num_bits(order);
+        /* Check the number of bits here so that an infinite loop is not possible */
+        if (order_bits < MIN_ECDSA_SIGN_ORDERBITS
+            || !BN_set_bit(k, order_bits))
+            goto ret;
+
+        do {
+            int res = 0;
+
+            if (dgst != NULL)
+                res = ossl_bn_gen_dsa_nonce_fixed_top(k, order, privkey,
+                    dgst, dgstlen, bn_ctx);
+            else
+                res = ossl_bn_priv_rand_range_fixed_top(k, order, 0, bn_ctx);
+
+            if (!res) {
+                ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED);
+                goto ret;
+            }
+        } while (ossl_bn_is_word_fixed_top(k, 0));
+
+        if (BN_bn2binpad(k, param + S390X_OFF_RN(len), len) == -1) {
+            ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED);
+            goto ret;
+        }
+
+        /* Turns KDSA internal nonce-generation off. */
+        fc |= S390X_KDSA_D;
+#else
         /*
          * Generate random k and copy to param block. RAND_priv_bytes_ex
          * is used instead of BN_priv_rand_range or BN_generate_dsa_nonce
@@ -195,6 +238,7 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
             ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED);
             goto ret;
         }
+#endif
     } else {
         bn_ctx = BN_CTX_secure_new_ex(ossl_ec_key_get_libctx(eckey));
         if (bn_ctx == NULL)