]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix S390 ECDSA Deterministic mode fails tests in FIPS mode.
authorslontis <shane.lontis@oracle.com>
Thu, 21 Aug 2025 08:18:23 +0000 (18:18 +1000)
committerslontis <shane.lontis@oracle.com>
Thu, 21 Aug 2025 08:18:23 +0000 (18:18 +1000)
Fixes #28313

Recently Deterministic ECDSA was added to the FIPS provider.

I cant run s390 directly but I suspect the call to
ossl_ec_group_do_inverse_ord() fails because it passes a NULL bn_ctx.

This potentially then calls ec_field_inverse_mod_ord() that has code in
it that fails in fips mode if the BN_CTX is not passed.

It cant create it internally since it does not know what the OSSL_LIB_CTX is,
which is required when creating a BN_CTX.

The solution is to create a BN_CTX that uses the ec_key lib ctx and pass
that in.

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28314)

crypto/ec/ecp_s390x_nistp.c

index f13f8bed242d975c0700e1311176c089b9f4192b..7549b0eeaf34dbec0c696152c04f430a9c3f88dd 100644 (file)
@@ -135,6 +135,7 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
     ECDSA_SIG *sig;
     const EC_GROUP *group;
     const BIGNUM *privkey;
+    BN_CTX *bn_ctx = NULL;
     int off;
 
     group = EC_KEY_get0_group(eckey);
@@ -189,8 +190,12 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
              goto ret;
          }
     } else {
+        bn_ctx = BN_CTX_secure_new_ex(ossl_ec_key_get_libctx(eckey));
+        if (bn_ctx == NULL)
+            goto ret;
+
         /* Reconstruct k = (k^-1)^-1. */
-        if (ossl_ec_group_do_inverse_ord(group, k, kinv, NULL) == 0
+        if (ossl_ec_group_do_inverse_ord(group, k, kinv, bn_ctx) == 0
             || BN_bn2binpad(k, param + S390X_OFF_RN(len), len) == -1) {
             ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
             goto ret;
@@ -212,6 +217,7 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
 
     ok = 1;
 ret:
+    BN_CTX_free(bn_ctx);
     OPENSSL_cleanse(param, sizeof(param));
     if (ok != 1) {
         ECDSA_SIG_free(sig);