Browse Source

Merge branch 'thirdparty_dev' into dev

# Conflicts:

nf

#	libs/openssl/crypto/conf/conf_mod.c

#	libs/openssl/crypto/init.c

#	libs/openssl/include/openssl/asn1.h
#	libs/openssl/include/openssl/bio.h
#	libs/openssl/include/openssl/cmp.h
#	libs/openssl/include/openssl/cms.h

#	libs/openssl/include/openssl/crmf.h
#	libs/openssl/include/openssl/crypto.h
#	libs/openssl/include/openssl/fipskey.h
#	libs/openssl/include/openssl/pkcs12.h
#	libs/openssl/include/openssl/ssl.h
#	libs/openssl/include/openssl/x509.h
#	libs/openssl/include/openssl/x509_vfy.h

#	libs/openssl/ssl/quic/quic_tls.c

#	libs/openssl/ssl/ssl_init.c
#	libs/openssl/ssl/ssl_lib.c

.in

.in

.in

.in

.in

.in

Source commit: 72e033c3ae49e8fe8d7e236dc7c4566ea71c43ef
Martin Prikryl 2 weeks ago
parent
commit
c8730275a1
100 changed files with 4785 additions and 1350 deletions
  1. 2 0
      libs/openssl/AUTHORS.md
  2. 122 8
      libs/openssl/INSTALL.md
  3. 2 2
      libs/openssl/crypto/asn1/a_dup.c
  4. 2 2
      libs/openssl/crypto/asn1/a_i2d_fp.c
  5. 14 8
      libs/openssl/crypto/asn1/a_int.c
  6. 3 2
      libs/openssl/crypto/asn1/a_object.c
  7. 2 3
      libs/openssl/crypto/asn1/a_strex.c
  8. 0 75
      libs/openssl/crypto/asn1/a_time.c
  9. 12 1
      libs/openssl/crypto/asn1/d2i_pr.c
  10. 3 6
      libs/openssl/crypto/asn1/f_int.c
  11. 2 4
      libs/openssl/crypto/asn1/f_string.c
  12. 8 1
      libs/openssl/crypto/asn1/p5_pbev2.c
  13. 23 5
      libs/openssl/crypto/asn1/p8_pkey.c
  14. 1 3
      libs/openssl/crypto/asn1/standard_methods.h
  15. 2 2
      libs/openssl/crypto/async/arch/async_posix.h
  16. 1 0
      libs/openssl/crypto/async/async_wait.c
  17. 10 7
      libs/openssl/crypto/bio/bio_addr.c
  18. 20 0
      libs/openssl/crypto/bio/bio_meth.c
  19. 23 3
      libs/openssl/crypto/bio/bio_sock.c
  20. 2 2
      libs/openssl/crypto/bio/bss_acpt.c
  21. 21 1
      libs/openssl/crypto/bio/bss_dgram_pair.c
  22. 0 9
      libs/openssl/crypto/bio/bss_file.c
  23. 1 1
      libs/openssl/crypto/bio/bss_mem.c
  24. 2 5
      libs/openssl/crypto/bn/bn_conv.c
  25. 2 2
      libs/openssl/crypto/bn/bn_exp.c
  26. 24 12
      libs/openssl/crypto/bn/bn_gcd.c
  27. 11 9
      libs/openssl/crypto/bn/bn_lib.c
  28. 3 2
      libs/openssl/crypto/bn/bn_mod.c
  29. 43 1
      libs/openssl/crypto/bn/bn_mont.c
  30. 3 3
      libs/openssl/crypto/bn/bn_nist.c
  31. 3 1
      libs/openssl/crypto/bn/rsaz_exp.h
  32. 20 7
      libs/openssl/crypto/cmac/cmac.c
  33. 18 3
      libs/openssl/crypto/cmp/cmp_err.c
  34. 54 4
      libs/openssl/crypto/cmp/cmp_local.h
  35. 2 1
      libs/openssl/crypto/cms/cms_asn1.c
  36. 8 4
      libs/openssl/crypto/cms/cms_env.c
  37. 3 1
      libs/openssl/crypto/cms/cms_kari.c
  38. 121 22
      libs/openssl/crypto/cms/cms_lib.c
  39. 5 0
      libs/openssl/crypto/cms/cms_local.h
  40. 52 9
      libs/openssl/crypto/cms/cms_sd.c
  41. 59 0
      libs/openssl/crypto/comp_methods.c
  42. 3 2
      libs/openssl/crypto/conf/conf_lib.c
  43. 26 4
      libs/openssl/crypto/conf/conf_mod.c
  44. 54 47
      libs/openssl/crypto/context.c
  45. 5 1
      libs/openssl/crypto/core_fetch.c
  46. 155 132
      libs/openssl/crypto/core_namemap.c
  47. 2 1
      libs/openssl/crypto/cpt_err.c
  48. 35 20
      libs/openssl/crypto/cpuid.c
  49. 31 18
      libs/openssl/crypto/crmf/crmf_err.c
  50. 22 32
      libs/openssl/crypto/crmf/crmf_local.h
  51. 204 0
      libs/openssl/crypto/defaults.c
  52. 4 3
      libs/openssl/crypto/des/set_key.c
  53. 32 4
      libs/openssl/crypto/dh/dh_check.c
  54. 7 9
      libs/openssl/crypto/dsa/dsa_ameth.c
  55. 17 7
      libs/openssl/crypto/dsa/dsa_pmeth.c
  56. 16 1
      libs/openssl/crypto/ec/curve25519.c
  57. 4 3
      libs/openssl/crypto/ec/curve448/curve448.c
  58. 23 1
      libs/openssl/crypto/ec/curve448/eddsa.c
  59. 2 3
      libs/openssl/crypto/ec/ec_backend.c
  60. 31 7
      libs/openssl/crypto/ec/ec_curve.c
  61. 6 0
      libs/openssl/crypto/ec/ec_key.c
  62. 4 0
      libs/openssl/crypto/ec/ec_lib.c
  63. 2 1
      libs/openssl/crypto/ec/ec_local.h
  64. 10 16
      libs/openssl/crypto/ec/ec_print.c
  65. 2 2
      libs/openssl/crypto/ec/ecp_mont.c
  66. 3 0
      libs/openssl/crypto/ec/ecx_key.c
  67. 108 6
      libs/openssl/crypto/encode_decode/decoder_lib.c
  68. 13 3
      libs/openssl/crypto/encode_decode/decoder_meth.c
  69. 94 19
      libs/openssl/crypto/encode_decode/decoder_pkey.c
  70. 182 1
      libs/openssl/crypto/encode_decode/encoder_lib.c
  71. 7 1
      libs/openssl/crypto/encode_decode/encoder_local.h
  72. 13 3
      libs/openssl/crypto/encode_decode/encoder_meth.c
  73. 47 15
      libs/openssl/crypto/evp/asymcipher.c
  74. 64 64
      libs/openssl/crypto/evp/bio_b64.c
  75. 6 2
      libs/openssl/crypto/evp/bio_ok.c
  76. 170 167
      libs/openssl/crypto/evp/ctrl_params_translate.c
  77. 3 4
      libs/openssl/crypto/evp/dh_support.c
  78. 120 40
      libs/openssl/crypto/evp/digest.c
  79. 4 3
      libs/openssl/crypto/evp/e_des3.c
  80. 52 14
      libs/openssl/crypto/evp/encode.c
  81. 402 24
      libs/openssl/crypto/evp/evp_enc.c
  82. 92 71
      libs/openssl/crypto/evp/evp_err.c
  83. 33 3
      libs/openssl/crypto/evp/evp_fetch.c
  84. 298 53
      libs/openssl/crypto/evp/evp_lib.c
  85. 45 1
      libs/openssl/crypto/evp/evp_local.h
  86. 29 21
      libs/openssl/crypto/evp/exchange.c
  87. 12 9
      libs/openssl/crypto/evp/kdf_meth.c
  88. 20 9
      libs/openssl/crypto/evp/kem.c
  89. 65 9
      libs/openssl/crypto/evp/keymgmt_meth.c
  90. 113 41
      libs/openssl/crypto/evp/m_sigver.c
  91. 16 1
      libs/openssl/crypto/evp/mac_lib.c
  92. 35 12
      libs/openssl/crypto/evp/mac_meth.c
  93. 2 2
      libs/openssl/crypto/evp/p5_crpt.c
  94. 13 6
      libs/openssl/crypto/evp/p_legacy.c
  95. 89 32
      libs/openssl/crypto/evp/p_lib.c
  96. 25 6
      libs/openssl/crypto/evp/pmeth_lib.c
  97. 314 0
      libs/openssl/crypto/evp/s_lib.c
  98. 639 162
      libs/openssl/crypto/evp/signature.c
  99. 242 0
      libs/openssl/crypto/evp/skeymgmt_meth.c
  100. 9 1
      libs/openssl/crypto/ffc/ffc_params.c

+ 2 - 0
libs/openssl/AUTHORS.md

@@ -12,6 +12,7 @@ Groups
 
  * OpenSSL Software Services, Inc.
  * OpenSSL Software Foundation, Inc.
+ * Google LLC
 
 Individuals
 -----------
@@ -48,4 +49,5 @@ Individuals
  * Tim Hudson
  * Tomáš Mráz
  * Ulf Möller
+ * Valerii Krygin
  * Viktor Dukhovni

+ 122 - 8
libs/openssl/INSTALL.md

@@ -52,6 +52,8 @@ To install OpenSSL, you will need:
  * Perl 5 with core modules (please read [NOTES-PERL.md](NOTES-PERL.md))
  * The Perl module `Text::Template` (please read [NOTES-PERL.md](NOTES-PERL.md))
  * an ANSI C compiler
+ * POSIX C library (at least POSIX.1-2008), or compatible types and
+   functionality.
  * a development environment in the form of development libraries and C
    header files
  * a supported operating system
@@ -65,6 +67,7 @@ issues and other details, please read one of these:
  * [Notes for the DOS platform with DJGPP](NOTES-DJGPP.md)
  * [Notes for the OpenVMS platform](NOTES-VMS.md)
  * [Notes for the HPE NonStop platform](NOTES-NONSTOP.md)
+ * [Notes on POSIX](NOTES-POSIX.md)
  * [Notes on Perl](NOTES-PERL.md)
  * [Notes on Valgrind](NOTES-VALGRIND.md)
 
@@ -507,11 +510,6 @@ This source is ignored by the FIPS provider.
 Use the `RDSEED` or `RDRAND` command on x86 or `RNDRRS` command on aarch64
 if provided by the CPU.
 
-### librandom
-
-Use librandom (not implemented yet).
-This source is ignored by the FIPS provider.
-
 ### none
 
 Disable automatic seeding.  This is the default on some operating systems where
@@ -523,6 +521,35 @@ at the end of this document.
 
 [rng]: #notes-on-random-number-generation
 
+### jitter
+
+When configured with `enable-jitter`, a "JITTER" RNG is compiled that
+can provide an alternative software seed source. It can be configured
+by setting `seed` option in `openssl.cnf`. A minimal `openssl.cnf` is
+shown below:
+
+    openssl_conf = openssl_init
+
+    [openssl_init]
+    random = random
+
+    [random]
+    seed=JITTER
+
+It uses a statically linked [jitterentropy-library] as the seed source.
+
+Additional configuration flags available:
+
+    --with-jitter-include=DIR
+
+The directory for the location of the jitterentropy.h include file, if
+it is outside the system include path.
+
+    --with-jitter-lib=DIR
+
+This is the directory containing the static libjitterentropy.a
+library, if it is outside the system library path.
+
 Setting the FIPS HMAC key
 -------------------------
 
@@ -754,6 +781,12 @@ Don't build support for Elliptic Curves.
 
 Don't build support for binary Elliptic Curves
 
+### no-tls-deprecated-ec
+
+Disable legacy TLS EC groups that were deprecated in RFC8422.  These are the
+Koblitz curves, B<secp160r1>, B<secp160r2>, B<secp192r1>, B<secp224r1>, and the
+binary Elliptic curves that would also be disabled by C<no-ec2m>.
+
 ### enable-ec_nistp_64_gcc_128
 
 Enable support for optimised implementations of some commonly used NIST
@@ -807,6 +840,26 @@ Build (and install) the FIPS provider
 Don't perform FIPS module run-time checks related to enforcement of security
 parameters such as minimum security strength of keys.
 
+### no-fips-post
+
+Don't perform FIPS module Power On Self Tests.
+
+This option MUST be used for debugging only as it makes the FIPS provider
+non-compliant. It is useful when setting breakpoints in FIPS algorithms.
+
+### enable-fips-jitter
+
+Use the CPU Jitter library as a FIPS validated entropy source.
+
+This option will only produce a compliant FIPS provider if you have:
+
+1. independently performed the required [SP 800-90B] entropy assessments;
+2. meet the minimum required entropy as specified by [jitterentropy-library];
+3. obtain an [ESV] certificate for the [jitterentropy-library] and
+4. have had the resulting FIPS provider certified by the [CMVP].
+
+Failure to do all of these will produce a non-compliant FIPS provider.
+
 ### enable-fuzz-libfuzzer, enable-fuzz-afl
 
 Build with support for fuzzing using either libfuzzer or AFL.
@@ -838,6 +891,16 @@ Disabling this also disables the legacy algorithms: MD2 (already disabled by def
 
 Don't generate dependencies.
 
+### no-ml-dsa
+
+Disable Module-Lattice-Based Digital Signature Standard (ML-DSA) support.
+ML-DSA is based on CRYSTALS-DILITHIUM. See [FIPS 204].
+
+### no-ml-kem
+
+Disable Module-Lattice-Based Key-Encapsulation Mechanism Standard (ML-KEM)
+support.  ML-KEM is based on CRYSTALS-KYBER. See [FIPS 203].
+
 ### no-module
 
 Don't build any dynamically loadable engines.
@@ -870,6 +933,10 @@ As synonym for `no-padlockeng`.  Deprecated and should not be used.
 
 Don't build with support for Position Independent Code.
 
+### enable-pie
+
+Build with support for Position Independent Execution.
+
 ### no-pinshared
 
 Don't pin the shared libraries.
@@ -923,6 +990,11 @@ Do not create shared libraries, only static ones.
 
 See [Notes on shared libraries](#notes-on-shared-libraries) below.
 
+### no-slh-dsa
+
+Disable Stateless Hash Based Digital Signature Standard support.
+(SLH-DSA is based on SPHINCS+. See [FIPS 205])
+
 ### no-sm2-precomp
 
 Disable using the SM2 precomputed table on aarch64 to make the library smaller.
@@ -1027,6 +1099,17 @@ Build with support for the integrated tracing api.
 
 See manual pages OSSL_trace_set_channel(3) and OSSL_trace_enabled(3) for details.
 
+### enable-sslkeylog
+
+Build with support for the SSLKEYLOGFILE environment variable
+
+When enabled, setting SSLKEYLOGFILE to a file path records the keys exchanged
+during a TLS handshake for use in analysis tools like wireshark.  Note that the
+use of this mechanism allows for decryption of application payloads found in
+captured packets using keys from the key log file and therefore has significant
+security consequences.  See Section 3 of
+[the draft standard for SSLKEYLOGFILE](https://datatracker.ietf.org/doc/draft-ietf-tls-keylogfile/)
+
 ### no-ts
 
 Don't build Time Stamping (TS) Authority support.
@@ -1113,6 +1196,10 @@ synonymous with `no-ssl3`.  Note this only affects version negotiation.
 OpenSSL will still provide the methods for applications to explicitly select
 the individual protocol versions.
 
+### no-integrity-only-ciphers
+
+Don't build support for integrity only ciphers in tls.
+
 ### no-{protocol}-method
 
     no-{ssl3|tls1|tls1_1|tls1_2|dtls1|dtls1_2}-method
@@ -1134,9 +1221,9 @@ Build with support for the specified algorithm.
 ### no-{algorithm}
 
     no-{aria|bf|blake2|camellia|cast|chacha|cmac|
-        des|dh|dsa|ecdh|ecdsa|idea|md4|mdc2|ocb|
-        poly1305|rc2|rc4|rmd160|scrypt|seed|
-        siphash|siv|sm2|sm3|sm4|whirlpool}
+        des|dh|dsa|ecdh|ecdsa|idea|md4|mdc2|ml-dsa|
+        ml-kem|ocb|poly1305|rc2|rc4|rmd160|scrypt|
+        seed|siphash|siv|sm2|sm3|sm4|whirlpool}
 
 Build without support for the specified algorithm.
 
@@ -1634,6 +1721,12 @@ described here.  Examine the Makefiles themselves for the full list.
     build_docs
                    Build all documentation components.
 
+    debuginfo
+                    On unix platforms, this target can be used to create .debug
+                    libraries, which separate the DWARF information in the
+                    shared library ELF files into a separate file for use
+                    in post-mortem (core dump) debugging
+
     clean
                    Remove all build artefacts and return the directory to a "clean"
                    state.
@@ -1958,3 +2051,24 @@ is used, as it is the version of the GNU assembler that will be checked.
 
 [10-main.conf]:
     Configurations/10-main.conf
+
+[CMVP]:
+    <https://csrc.nist.gov/projects/cryptographic-module-validation-program>
+
+[ESV]:
+    <https://csrc.nist.gov/Projects/cryptographic-module-validation-program/entropy-validations>
+
+[FIPS 203]:
+    <https://csrc.nist.gov/pubs/fips/203/final>
+
+[FIPS 204]:
+    <https://csrc.nist.gov/pubs/fips/204/final>
+
+[SP 800-90B]:
+    <https://csrc.nist.gov/pubs/sp/800/90/b/final>
+
+[jitterentropy-library]:
+    <https://github.com/smuellerDD/jitterentropy-library>
+
+[FIPS 205]:
+    <https://csrc.nist.gov/pubs/fips/205/final>

+ 2 - 2
libs/openssl/crypto/asn1/a_dup.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -75,7 +75,7 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
     }
 
     i = ASN1_item_i2d(x, &b, it);
-    if (b == NULL) {
+    if (i < 0 || b == NULL) {
         ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         return NULL;
     }

+ 2 - 2
libs/openssl/crypto/asn1/a_i2d_fp.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -88,7 +88,7 @@ int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, const void *x)
     int i, j = 0, n, ret = 1;
 
     n = ASN1_item_i2d(x, &b, it);
-    if (b == NULL) {
+    if (n < 0 || b == NULL) {
         ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         return 0;
     }

+ 14 - 8
libs/openssl/crypto/asn1/a_int.c

@@ -40,7 +40,7 @@ int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
         return ret;
 }
 
-/*-
+/*
  * This converts a big endian buffer and sign into its content encoding.
  * This is used for INTEGER and ENUMERATED types.
  * The internal representation is an ASN1_STRING whose data is a big endian
@@ -260,12 +260,16 @@ static int asn1_get_int64(int64_t *pr, const unsigned char *b, size_t blen,
         return 0;
     if (neg) {
         if (r <= INT64_MAX) {
-            /* Most significant bit is guaranteed to be clear, negation
-             * is guaranteed to be meaningful in platform-neutral sense. */
+            /*
+             * Most significant bit is guaranteed to be clear, negation
+             * is guaranteed to be meaningful in platform-neutral sense.
+             */
             *pr = -(int64_t)r;
         } else if (r == ABS_INT64_MIN) {
-            /* This never happens if INT64_MAX == ABS_INT64_MIN, e.g.
-             * on ones'-complement system. */
+            /*
+             * This never happens if INT64_MAX == ABS_INT64_MIN, e.g.
+             * on ones'-complement system.
+             */
             *pr = (int64_t)(0 - r);
         } else {
             ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
@@ -345,11 +349,13 @@ static int asn1_string_set_int64(ASN1_STRING *a, int64_t r, int itype)
 
     a->type = itype;
     if (r < 0) {
-        /* Most obvious '-r' triggers undefined behaviour for most
+        /*
+         * Most obvious '-r' triggers undefined behaviour for most
          * common INT64_MIN. Even though below '0 - (uint64_t)r' can
          * appear two's-complement centric, it does produce correct/
-         * expected result even on one's-complement. This is because
-         * cast to unsigned has to change bit pattern... */
+         * expected result even on ones' complement. This is because
+         * cast to unsigned has to change bit pattern...
+         */
         off = asn1_put_uint64(tbuf, 0 - (uint64_t)r);
         a->type |= V_ASN1_NEG;
     } else {

+ 3 - 2
libs/openssl/crypto/asn1/a_object.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -198,7 +198,8 @@ int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
     }
     if (i <= 0) {
         i = BIO_write(bp, "<INVALID>", 9);
-        i += BIO_dump(bp, (const char *)a->data, a->length);
+        if (i > 0)
+            i += BIO_dump(bp, (const char *)a->data, a->length);
         return i;
     }
     BIO_write(bp, p, i);

+ 2 - 3
libs/openssl/crypto/asn1/a_strex.c

@@ -235,15 +235,14 @@ static int do_buf(unsigned char *buf, int buflen,
 static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
                        int buflen)
 {
-    static const char hexdig[] = "0123456789ABCDEF";
     unsigned char *p, *q;
     char hextmp[2];
+
     if (arg) {
         p = buf;
         q = buf + buflen;
         while (p != q) {
-            hextmp[0] = hexdig[*p >> 4];
-            hextmp[1] = hexdig[*p & 0xf];
+            ossl_to_hex(hextmp, *p);
             if (!io_ch(arg, hextmp, 2))
                 return -1;
             p++;

+ 0 - 75
libs/openssl/crypto/asn1/a_time.c

@@ -586,78 +586,3 @@ int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b)
         return -1;
     return 0;
 }
-
-/*
- * tweak for Windows
- */
-#ifdef WIN32
-# define timezone _timezone
-#endif
-
-#if defined(__FreeBSD__) || defined(__wasi__)
-# define USE_TIMEGM
-#endif
-
-time_t ossl_asn1_string_to_time_t(const char *asn1_string)
-{
-    ASN1_TIME *timestamp_asn1 = NULL;
-    struct tm *timestamp_tm = NULL;
-#if defined(__DJGPP__)
-    char *tz = NULL;
-#elif !defined(USE_TIMEGM)
-    time_t timestamp_local;
-#endif
-    time_t timestamp_utc;
-
-    timestamp_asn1 = ASN1_TIME_new();
-    if (!ASN1_TIME_set_string(timestamp_asn1, asn1_string))
-    {
-        ASN1_TIME_free(timestamp_asn1);
-        return -1;
-    }
-
-    timestamp_tm = OPENSSL_malloc(sizeof(*timestamp_tm));
-    if (timestamp_tm == NULL) {
-        ASN1_TIME_free(timestamp_asn1);
-        return -1;
-    }
-    if (!(ASN1_TIME_to_tm(timestamp_asn1, timestamp_tm))) {
-        OPENSSL_free(timestamp_tm);
-        ASN1_TIME_free(timestamp_asn1);
-        return -1;
-    }
-    ASN1_TIME_free(timestamp_asn1);
-
-#if defined(__DJGPP__)
-    /*
-     * This is NOT thread-safe.  Do not use this method for platforms other
-     * than djgpp.
-     */
-    tz = getenv("TZ");
-    if (tz != NULL) {
-        tz = OPENSSL_strdup(tz);
-        if (tz == NULL) {
-            OPENSSL_free(timestamp_tm);
-            return -1;
-        }
-    }
-    setenv("TZ", "UTC", 1);
-
-    timestamp_utc = mktime(timestamp_tm);
-
-    if (tz != NULL) {
-        setenv("TZ", tz, 1);
-        OPENSSL_free(tz);
-    } else {
-        unsetenv("TZ");
-    }
-#elif defined(USE_TIMEGM)
-    timestamp_utc = timegm(timestamp_tm);
-#else
-    timestamp_local = mktime(timestamp_tm);
-    timestamp_utc = timestamp_local - timezone;
-#endif
-    OPENSSL_free(timestamp_tm);
-
-    return timestamp_utc;
-}

+ 12 - 1
libs/openssl/crypto/asn1/d2i_pr.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -21,6 +21,7 @@
 #include <openssl/asn1.h>
 #include "crypto/asn1.h"
 #include "crypto/evp.h"
+#include "crypto/x509.h"
 #include "internal/asn1.h"
 #include "internal/sizes.h"
 
@@ -51,6 +52,16 @@ d2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp,
     p8info = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, len);
     ERR_pop_to_mark();
     if (p8info != NULL) {
+        int64_t v;
+
+        /* ascertain version is 0 or 1 as per RFC5958 */
+        if (!ASN1_INTEGER_get_int64(&v, p8info->version)
+            || (v != 0 && v != 1)) {
+            *pp = p;
+            ERR_raise(ERR_LIB_ASN1, ASN1_R_ASN1_PARSE_ERROR);
+            PKCS8_PRIV_KEY_INFO_free(p8info);
+            return NULL;
+        }
         if (key_name == NULL
                 && PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8info)
                 && OBJ_obj2txt(keytypebuf, sizeof(keytypebuf), algoid, 0))

+ 3 - 6
libs/openssl/crypto/asn1/f_int.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -16,7 +16,6 @@
 int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
 {
     int i, n = 0;
-    static const char *h = "0123456789ABCDEF";
     char buf[2];
 
     if (a == NULL)
@@ -39,8 +38,7 @@ int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
                     goto err;
                 n += 2;
             }
-            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
-            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+            ossl_to_hex(buf, a->data[i]);
             if (BIO_write(bp, buf, 2) != 2)
                 goto err;
             n += 2;
@@ -76,8 +74,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
         again = (buf[i - 1] == '\\');
 
         for (j = 0; j < i; j++) {
-            if (!ossl_isxdigit(buf[j]))
-            {
+            if (!ossl_isxdigit(buf[j])) {
                 i = j;
                 break;
             }

+ 2 - 4
libs/openssl/crypto/asn1/f_string.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -16,7 +16,6 @@
 int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type)
 {
     int i, n = 0;
-    static const char *h = "0123456789ABCDEF";
     char buf[2];
 
     if (a == NULL)
@@ -33,8 +32,7 @@ int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type)
                     goto err;
                 n += 2;
             }
-            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
-            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+            ossl_to_hex(buf, a->data[i]);
             if (BIO_write(bp, buf, 2) != 2)
                 goto err;
             n += 2;

+ 8 - 1
libs/openssl/crypto/asn1/p5_pbev2.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 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
@@ -35,6 +35,13 @@ ASN1_SEQUENCE(PBKDF2PARAM) = {
 
 IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
 
+ASN1_SEQUENCE(PBMAC1PARAM) = {
+    ASN1_SIMPLE(PBMAC1PARAM, keyDerivationFunc, X509_ALGOR),
+    ASN1_SIMPLE(PBMAC1PARAM, messageAuthScheme, X509_ALGOR)
+} ASN1_SEQUENCE_END(PBMAC1PARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBMAC1PARAM)
+
 /*
  * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
  * this is horrible! Extended version to allow application supplied PRF NID

+ 23 - 5
libs/openssl/crypto/asn1/p8_pkey.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2025 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
@@ -17,11 +17,25 @@
 static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
                    void *exarg)
 {
-    /* Since the structure must still be valid use ASN1_OP_FREE_PRE */
-    if (operation == ASN1_OP_FREE_PRE) {
-        PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
+    PKCS8_PRIV_KEY_INFO *key;
+    int version;
+
+    switch (operation) {
+    case ASN1_OP_FREE_PRE:
+        /* The structure is still valid during ASN1_OP_FREE_PRE */
+        key = (PKCS8_PRIV_KEY_INFO *)*pval;
         if (key->pkey)
             OPENSSL_cleanse(key->pkey->data, key->pkey->length);
+        break;
+    case ASN1_OP_D2I_POST:
+        /* Insist on a valid version now that the structure is decoded */
+        key = (PKCS8_PRIV_KEY_INFO *)*pval;
+        version = ASN1_INTEGER_get(key->version);
+        if (version < 0 || version > 1)
+            return 0;
+        if (version == 0 && key->kpub != NULL)
+            return 0;
+        break;
     }
     return 1;
 }
@@ -30,7 +44,8 @@ ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
         ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
         ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
         ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING),
-        ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
+        ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0),
+        ASN1_IMP_OPT(PKCS8_PRIV_KEY_INFO, kpub, ASN1_BIT_STRING, 1)
 } ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
 
 IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
@@ -40,6 +55,9 @@ int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
                     int ptype, void *pval, unsigned char *penc, int penclen)
 {
     if (version >= 0) {
+        /* We only support PKCS#8 v1 (0) and v2 (1). */
+        if (version > 1)
+            return 0;
         if (!ASN1_INTEGER_set(priv->version, version))
             return 0;
     }

+ 1 - 3
libs/openssl/crypto/asn1/standard_methods.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2025 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
@@ -23,7 +23,6 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
     &ossl_dsa_asn1_meths[1],
     &ossl_dsa_asn1_meths[2],
     &ossl_dsa_asn1_meths[3],
-    &ossl_dsa_asn1_meths[4],
 #endif
 #ifndef OPENSSL_NO_EC
     &ossl_eckey_asn1_meth,
@@ -42,4 +41,3 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
     &ossl_sm2_asn1_meth,
 #endif
 };
-

+ 2 - 2
libs/openssl/crypto/async/arch/async_posix.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2024 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
@@ -18,7 +18,7 @@
 # include <unistd.h>
 
 # if _POSIX_VERSION >= 200112L \
-     && (_POSIX_VERSION < 200809L || defined(__GLIBC__))
+    && (_POSIX_VERSION < 200809L || defined(__GLIBC__) || defined(__FreeBSD__))
 
 # include <pthread.h>
 

+ 1 - 0
libs/openssl/crypto/async/async_wait.c

@@ -40,6 +40,7 @@ void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx)
 
     OPENSSL_free(ctx);
 }
+
 int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key,
                                OSSL_ASYNC_FD fd, void *custom_data,
                                void (*cleanup)(ASYNC_WAIT_CTX *, const void *,

+ 10 - 7
libs/openssl/crypto/bio/bio_addr.c

@@ -780,16 +780,19 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
         /* Windows doesn't seem to have in_addr_t */
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
         static uint32_t he_fallback_address;
-        static const char *he_fallback_addresses[] =
-            { (char *)&he_fallback_address, NULL };
+        static const char *he_fallback_addresses[] = {
+            (char *)&he_fallback_address, NULL
+        };
 #else
         static in_addr_t he_fallback_address;
-        static const char *he_fallback_addresses[] =
-            { (char *)&he_fallback_address, NULL };
+        static const char *he_fallback_addresses[] = {
+            (char *)&he_fallback_address, NULL
+        };
 #endif
-        static const struct hostent he_fallback =
-            { NULL, NULL, AF_INET, sizeof(he_fallback_address),
-              (char **)&he_fallback_addresses };
+        static const struct hostent he_fallback = {
+            NULL, NULL, AF_INET, sizeof(he_fallback_address),
+            (char **)&he_fallback_addresses
+        };
 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
 # pragma pointer_size restore
 #endif

+ 20 - 0
libs/openssl/crypto/bio/bio_meth.c

@@ -55,6 +55,7 @@ void BIO_meth_free(BIO_METHOD *biom)
     }
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 int (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int)
 {
     return biom->bwrite_old;
@@ -65,6 +66,7 @@ int (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_
 {
     return biom->bwrite;
 }
+#endif
 
 /* Conversion for old style bwrite to new style */
 int bwrite_conv(BIO *bio, const char *data, size_t datal, size_t *written)
@@ -102,6 +104,7 @@ int BIO_meth_set_write_ex(BIO_METHOD *biom,
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int)
 {
     return biom->bread_old;
@@ -111,6 +114,7 @@ int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size
 {
     return biom->bread;
 }
+#endif
 
 /* Conversion for old style bread to new style */
 int bread_conv(BIO *bio, char *data, size_t datal, size_t *readbytes)
@@ -148,10 +152,12 @@ int BIO_meth_set_read_ex(BIO_METHOD *biom,
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *)
 {
     return biom->bputs;
 }
+#endif
 
 int BIO_meth_set_puts(BIO_METHOD *biom,
                       int (*bputs) (BIO *, const char *))
@@ -160,10 +166,12 @@ int BIO_meth_set_puts(BIO_METHOD *biom,
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int)
 {
     return biom->bgets;
 }
+#endif
 
 int BIO_meth_set_gets(BIO_METHOD *biom,
                       int (*bgets) (BIO *, char *, int))
@@ -172,10 +180,12 @@ int BIO_meth_set_gets(BIO_METHOD *biom,
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *)
 {
     return biom->ctrl;
 }
+#endif
 
 int BIO_meth_set_ctrl(BIO_METHOD *biom,
                       long (*ctrl) (BIO *, int, long, void *))
@@ -184,10 +194,12 @@ int BIO_meth_set_ctrl(BIO_METHOD *biom,
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 int (*BIO_meth_get_create(const BIO_METHOD *biom)) (BIO *)
 {
     return biom->create;
 }
+#endif
 
 int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
 {
@@ -195,10 +207,12 @@ int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 int (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *)
 {
     return biom->destroy;
 }
+#endif
 
 int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
 {
@@ -206,10 +220,12 @@ int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom)) (BIO *, int, BIO_info_cb *)
 {
     return biom->callback_ctrl;
 }
+#endif
 
 int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
                                long (*callback_ctrl) (BIO *, int,
@@ -226,9 +242,11 @@ int BIO_meth_set_sendmmsg(BIO_METHOD *biom,
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 int (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) {
     return biom->bsendmmsg;
 }
+#endif
 
 int BIO_meth_set_recvmmsg(BIO_METHOD *biom,
                           int (*brecvmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *))
@@ -237,6 +255,8 @@ int BIO_meth_set_recvmmsg(BIO_METHOD *biom,
     return 1;
 }
 
+#ifndef OPENSSL_NO_DEPRECATED_3_5
 int (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) {
     return biom->brecvmmsg;
 }
+#endif

+ 23 - 3
libs/openssl/crypto/bio/bio_sock.c

@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "bio_local.h"
+
 #ifndef OPENSSL_NO_SOCK
 # define SOCKET_PROTOCOL IPPROTO_TCP
 # ifdef SO_MAXCONN
@@ -38,6 +39,7 @@ static int wsa_init_done = 0;
 #   include <sys/select.h>
 #  endif
 # endif
+# include "internal/sockets.h" /* for openssl_fdset() */
 
 # ifndef OPENSSL_NO_DEPRECATED_1_1_0
 int BIO_get_host_ip(const char *str, unsigned char *ip)
@@ -428,15 +430,16 @@ int BIO_sock_info(int sock,
  */
 int BIO_socket_wait(int fd, int for_read, time_t max_time)
 {
+# if defined(OPENSSL_SYS_WINDOWS) || !defined(POLLIN)
     fd_set confds;
     struct timeval tv;
     time_t now;
 
-#ifdef _WIN32
+#  ifdef _WIN32
     if ((SOCKET)fd == INVALID_SOCKET)
-#else
+#  else
     if (fd < 0 || fd >= FD_SETSIZE)
-#endif
+#  endif
         return -1;
     if (max_time == 0)
         return 1;
@@ -451,5 +454,22 @@ int BIO_socket_wait(int fd, int for_read, time_t max_time)
     tv.tv_sec = (long)(max_time - now); /* might overflow */
     return select(fd + 1, for_read ? &confds : NULL,
                   for_read ? NULL : &confds, NULL, &tv);
+# else
+    struct pollfd confds;
+    time_t now;
+
+    if (fd < 0)
+        return -1;
+    if (max_time == 0)
+        return 1;
+
+    now = time(NULL);
+    if (max_time < now)
+        return 0;
+
+    confds.fd = fd;
+    confds.events = for_read ? POLLIN : POLLOUT;
+    return poll(&confds, 1, (int)(max_time - now) * 1000);
+# endif
 }
 #endif /* !defined(OPENSSL_NO_SOCK) */

+ 2 - 2
libs/openssl/crypto/bio/bss_acpt.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -356,7 +356,7 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
         BIO_free(bio);
     else if (s >= 0)
         BIO_closesocket(s);
-  end:
+ end:
     return ret;
 }
 

+ 21 - 1
libs/openssl/crypto/bio/bss_dgram_pair.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -256,6 +256,8 @@ struct bio_dgram_pair_st {
     size_t mtu;
     /* Capability flags. */
     uint32_t cap;
+    /* The local address to use (if set) */
+    BIO_ADDR *local_addr;
     /*
      * This lock protects updates to our rbuf. Since writes are directed to our
      * own rbuf, this means we use this lock for writes and our peer's lock for
@@ -405,6 +407,8 @@ static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1)
     ring_buf_destroy(&b1->rbuf);
     bio1->init = 0;
 
+    BIO_ADDR_free(b1->local_addr);
+
     /* Early return if we don't have a peer. */
     if (b1->peer == NULL)
         return 1;
@@ -634,6 +638,16 @@ static int dgram_pair_ctrl_set_mtu(BIO *bio, size_t mtu)
     return 1;
 }
 
+/* BIO_dgram_set0_local_addr (BIO_CTRL_DGRAM_SET0_LOCAL_ADDR) */
+static int dgram_pair_ctrl_set0_local_addr(BIO *bio, BIO_ADDR *addr)
+{
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    BIO_ADDR_free(b->local_addr);
+    b->local_addr = addr;
+    return 1;
+}
+
 /* Partially threadsafe (some commands) */
 static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
 {
@@ -731,6 +745,10 @@ static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
         ret = (long)dgram_pair_ctrl_set_mtu(bio, (uint32_t)num);
         break;
 
+    case BIO_CTRL_DGRAM_SET0_LOCAL_ADDR:
+        ret = (long)dgram_pair_ctrl_set0_local_addr(bio, (BIO_ADDR *)ptr);
+        break;
+
     /*
      * BIO_eof: Returns whether this half of the BIO pair is empty of data to
      * read.
@@ -1230,6 +1248,8 @@ static ossl_ssize_t dgram_pair_write_actual(BIO *bio, const char *buf, size_t sz
 
     hdr.len = sz;
     hdr.dst_addr = (peer != NULL ? *peer : zero_addr);
+    if (local == NULL)
+        local = b->local_addr;
     hdr.src_addr = (local != NULL ? *local : zero_addr);
 
     saved_idx   = b->rbuf.idx[0];

+ 0 - 9
libs/openssl/crypto/bio/bss_file.c

@@ -235,15 +235,6 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
                 _setmode(fd, _O_TEXT);
             else
                 _setmode(fd, _O_BINARY);
-            /*
-             * Reports show that ftell() isn't trustable in text mode.
-             * This has been confirmed as a bug in the Universal C RTL, see
-             * https://developercommunity.visualstudio.com/content/problem/425878/fseek-ftell-fail-in-text-mode-for-unix-style-text.html
-             * The suggested work-around from Microsoft engineering is to
-             * turn off buffering until the bug is resolved.
-             */
-            if ((num & BIO_FP_TEXT) != 0)
-                setvbuf((FILE *)ptr, NULL, _IONBF, 0);
 # elif defined(OPENSSL_SYS_MSDOS)
             int fd = fileno((FILE *)ptr);
             /* Set correct text/binary mode */

+ 1 - 1
libs/openssl/crypto/bio/bss_mem.c

@@ -76,7 +76,7 @@ const BIO_METHOD *BIO_s_mem(void)
 
 const BIO_METHOD *BIO_s_secmem(void)
 {
-    return(&secmem_method);
+    return &secmem_method;
 }
 
 BIO *BIO_new_mem_buf(const void *buf, int len)

+ 2 - 5
libs/openssl/crypto/bn/bn_conv.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -11,8 +11,6 @@
 #include "crypto/ctype.h"
 #include "bn_local.h"
 
-static const char Hex[] = "0123456789ABCDEF";
-
 /* Must 'OPENSSL_free' the returned data */
 char *BN_bn2hex(const BIGNUM *a)
 {
@@ -33,8 +31,7 @@ char *BN_bn2hex(const BIGNUM *a)
             /* strip leading zeros */
             v = (int)((a->d[i] >> j) & 0xff);
             if (z || v != 0) {
-                *p++ = Hex[v >> 4];
-                *p++ = Hex[v & 0x0f];
+                p += ossl_to_hex(p, v);
                 z = 1;
             }
         }

+ 2 - 2
libs/openssl/crypto/bn/bn_exp.c

@@ -1452,7 +1452,7 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 /*
  * This is a variant of modular exponentiation optimization that does
  * parallel 2-primes exponentiation using 256-bit (AVX512VL) AVX512_IFMA ISA
- * in 52-bit binary redundant representation.
+ * or AVX_IFMA ISA in 52-bit binary redundant representation.
  * If such instructions are not available, or input data size is not supported,
  * it falls back to two BN_mod_exp_mont_consttime() calls.
  */
@@ -1468,7 +1468,7 @@ int BN_mod_exp_mont_consttime_x2(BIGNUM *rr1, const BIGNUM *a1, const BIGNUM *p1
     BN_MONT_CTX *mont1 = NULL;
     BN_MONT_CTX *mont2 = NULL;
 
-    if (ossl_rsaz_avx512ifma_eligible() &&
+    if ((ossl_rsaz_avx512ifma_eligible() || ossl_rsaz_avxifma_eligible()) &&
         (((a1->top == 16) && (p1->top == 16) && (BN_num_bits(m1) == 1024) &&
           (a2->top == 16) && (p2->top == 16) && (BN_num_bits(m2) == 1024)) ||
          ((a1->top == 24) && (p1->top == 24) && (BN_num_bits(m1) == 1536) &&

+ 24 - 12
libs/openssl/crypto/bn/bn_gcd.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -9,6 +9,7 @@
 
 #include "internal/cryptlib.h"
 #include "bn_local.h"
+#include "internal/constant_time.h"
 
 /*
  * bn_mod_inverse_no_branch is a special version of BN_mod_inverse. It does
@@ -580,8 +581,8 @@ end:
 int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
 {
     BIGNUM *g, *temp = NULL;
-    BN_ULONG mask = 0;
-    int i, j, top, rlen, glen, m, bit = 1, delta = 1, cond = 0, shifts = 0, ret = 0;
+    BN_ULONG pow2_numbits, pow2_numbits_temp, pow2_condition_mask, pow2_flag;
+    int i, j, top, rlen, glen, m, delta = 1, cond = 0, pow2_shifts, ret = 0;
 
     /* Note 2: zero input corner cases are not constant-time since they are
      * handled immediately. An attacker can run an attack under this
@@ -611,18 +612,29 @@ int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
         goto err;
 
     /* find shared powers of two, i.e. "shifts" >= 1 */
+    pow2_flag = 1;
+    pow2_shifts = 0;
+    pow2_numbits = 0;
     for (i = 0; i < r->dmax && i < g->dmax; i++) {
-        mask = ~(r->d[i] | g->d[i]);
-        for (j = 0; j < BN_BITS2; j++) {
-            bit &= mask;
-            shifts += bit;
-            mask >>= 1;
-        }
+        pow2_numbits_temp = r->d[i] | g->d[i];
+        pow2_condition_mask = constant_time_is_zero_bn(pow2_flag);
+        pow2_flag &= constant_time_is_zero_bn(pow2_numbits_temp);
+        pow2_shifts += pow2_flag;
+        pow2_numbits = constant_time_select_bn(pow2_condition_mask,
+                                               pow2_numbits, pow2_numbits_temp);
+    }
+    pow2_numbits = ~pow2_numbits;
+    pow2_shifts *= BN_BITS2;
+    pow2_flag = 1;
+    for (j = 0; j < BN_BITS2; j++) {
+        pow2_flag &= pow2_numbits;
+        pow2_shifts += pow2_flag;
+        pow2_numbits >>= 1;
     }
 
     /* subtract shared powers of two; shifts >= 1 */
-    if (!BN_rshift(r, r, shifts)
-        || !BN_rshift(g, g, shifts))
+    if (!BN_rshift(r, r, pow2_shifts)
+        || !BN_rshift(g, g, pow2_shifts))
         goto err;
 
     /* expand to biggest nword, with room for a possible extra word */
@@ -665,7 +677,7 @@ int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
     /* remove possible negative sign */
     r->neg = 0;
     /* add powers of 2 removed, then correct the artificial shift */
-    if (!BN_lshift(r, r, shifts)
+    if (!BN_lshift(r, r, pow2_shifts)
         || !BN_rshift1(r, r))
         goto err;
 

+ 11 - 9
libs/openssl/crypto/bn/bn_lib.c

@@ -82,8 +82,9 @@ int BN_get_params(int which)
 const BIGNUM *BN_value_one(void)
 {
     static const BN_ULONG data_one = 1L;
-    static const BIGNUM const_one =
-        { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };
+    static const BIGNUM const_one = {
+        (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA
+    };
 
     return &const_one;
 }
@@ -251,13 +252,14 @@ BIGNUM *BN_new(void)
     return ret;
 }
 
- BIGNUM *BN_secure_new(void)
- {
-     BIGNUM *ret = BN_new();
-     if (ret != NULL)
-         ret->flags |= BN_FLG_SECURE;
-     return ret;
- }
+BIGNUM *BN_secure_new(void)
+{
+    BIGNUM *ret = BN_new();
+
+    if (ret != NULL)
+        ret->flags |= BN_FLG_SECURE;
+    return ret;
+}
 
 /* This is used by bn_expand2() */
 /* The caller MUST check that words > b->dmax before calling this */

+ 3 - 2
libs/openssl/crypto/bn/bn_mod.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2024 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
@@ -8,6 +8,7 @@
  */
 
 #include "internal/cryptlib.h"
+#include "internal/nelem.h"
 #include "bn_local.h"
 
 int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
@@ -61,7 +62,7 @@ int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
     if (bn_wexpand(r, mtop) == NULL)
         return 0;
 
-    if (mtop > sizeof(storage) / sizeof(storage[0])) {
+    if (mtop > OSSL_NELEM(storage)) {
         tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG));
         if (tp == NULL)
             return 0;

+ 43 - 1
libs/openssl/crypto/bn/bn_mont.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -465,3 +465,45 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock,
     CRYPTO_THREAD_unlock(lock);
     return ret;
 }
+
+int ossl_bn_mont_ctx_set(BN_MONT_CTX *ctx, const BIGNUM *modulus, int ri, const unsigned char *rr,
+                         size_t rrlen, uint32_t nlo, uint32_t nhi)
+{
+    if (BN_copy(&ctx->N, modulus) == NULL)
+        return 0;
+    if (BN_bin2bn(rr, rrlen, &ctx->RR) == NULL)
+        return 0;
+    ctx->ri = ri;
+#if (BN_BITS2 <= 32) && defined(OPENSSL_BN_ASM_MONT)
+    ctx->n0[0] = nlo;
+    ctx->n0[1] = nhi;
+#elif BN_BITS2 <= 32
+    ctx->n0[0] = nlo;
+    ctx->n0[1] = 0;
+#else
+    ctx->n0[0] = ((BN_ULONG)nhi << 32)| nlo;
+    ctx->n0[1] = 0;
+#endif
+
+    return 1;
+}
+
+int ossl_bn_mont_ctx_eq(const BN_MONT_CTX *m1, const BN_MONT_CTX *m2)
+{
+    if (m1->ri != m2->ri)
+        return 0;
+    if (BN_cmp(&m1->RR, &m2->RR) != 0)
+        return 0;
+    if (m1->flags != m2->flags)
+        return 0;
+#ifdef MONT_WORD
+    if (m1->n0[0] != m2->n0[0])
+        return 0;
+    if (m1->n0[1] != m2->n0[1])
+        return 0;
+#else
+    if (BN_cmp(&m1->Ni, &m2->Ni) != 0)
+        return 0;
+#endif
+    return 1;
+}

+ 3 - 3
libs/openssl/crypto/bn/bn_nist.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2024 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
@@ -84,8 +84,8 @@ static const BN_ULONG _nist_p_384_sqr[] = {
     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
 };
 
-static const BN_ULONG _nist_p_521[] =
-    { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+static const BN_ULONG _nist_p_521[] = {
+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,

+ 3 - 1
libs/openssl/crypto/bn/rsaz_exp.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2013-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2020, Intel Corporation. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -40,6 +40,8 @@ void RSAZ_512_mod_exp(BN_ULONG result[8],
 
 int ossl_rsaz_avx512ifma_eligible(void);
 
+int ossl_rsaz_avxifma_eligible(void);
+
 int ossl_rsaz_mod_exp_avx512_x2(BN_ULONG *res1,
                                 const BN_ULONG *base1,
                                 const BN_ULONG *exponent1,

+ 20 - 7
libs/openssl/crypto/cmac/cmac.c

@@ -19,6 +19,7 @@
 #include "internal/cryptlib.h"
 #include <openssl/cmac.h>
 #include <openssl/err.h>
+#include "crypto/cmac.h"
 
 #define LOCAL_BUF_SIZE 2048
 struct CMAC_CTX_st {
@@ -107,8 +108,9 @@ int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
     return 1;
 }
 
-int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
-              const EVP_CIPHER *cipher, ENGINE *impl)
+int ossl_cmac_init(CMAC_CTX *ctx, const void *key, size_t keylen,
+                   const EVP_CIPHER *cipher, ENGINE *impl,
+                   const OSSL_PARAM param[])
 {
     static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 };
     int block_len;
@@ -118,7 +120,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
         /* Not initialised */
         if (ctx->nlast_block == -1)
             return 0;
-        if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
+        if (!EVP_EncryptInit_ex2(ctx->cctx, NULL, NULL, zero_iv, param))
             return 0;
         block_len = EVP_CIPHER_CTX_get_block_size(ctx->cctx);
         if (block_len == 0)
@@ -131,8 +133,13 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
     if (cipher != NULL) {
         /* Ensure we can't use this ctx until we also have a key */
         ctx->nlast_block = -1;
-        if (!EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL))
-            return 0;
+        if (impl != NULL) {
+            if (!EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL))
+                return 0;
+        } else {
+            if (!EVP_EncryptInit_ex2(ctx->cctx, cipher, NULL, NULL, param))
+                return 0;
+        }
     }
     /* Non-NULL key means initialisation complete */
     if (key != NULL) {
@@ -144,7 +151,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
             return 0;
         if (EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen) <= 0)
             return 0;
-        if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, key, zero_iv))
+        if (!EVP_EncryptInit_ex2(ctx->cctx, NULL, key, zero_iv, param))
             return 0;
         if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) < 0)
             return 0;
@@ -154,7 +161,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
         make_kn(ctx->k2, ctx->k1, bl);
         OPENSSL_cleanse(ctx->tbl, bl);
         /* Reset context again ready for first data block */
-        if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
+        if (!EVP_EncryptInit_ex2(ctx->cctx, NULL, NULL, zero_iv, param))
             return 0;
         /* Zero tbl so resume works */
         memset(ctx->tbl, 0, bl);
@@ -163,6 +170,12 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
     return 1;
 }
 
+int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
+              const EVP_CIPHER *cipher, ENGINE *impl)
+{
+    return ossl_cmac_init(ctx, key, keylen, cipher, impl, NULL);
+}
+
 int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
 {
     const unsigned char *data = in;

+ 18 - 3
libs/openssl/crypto/cmp/cmp_err.c

@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -79,18 +79,28 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_EXPECTED_POLLREQ), "expected pollreq"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_BUILDING_OWN_CHAIN),
     "failed building own chain"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_CENTRAL_GEN_KEY),
+     "failed extracting central gen key"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
     "failed extracting pubkey"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM),
     "failure obtaining random"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAIL_INFO_OUT_OF_RANGE),
     "fail info out of range"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GENERATE_CERTREQTEMPLATE),
+    "generate certreqtemplate"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GENERATE_CRLSTATUS),
+    "error creating crlstatus"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GETTING_GENP), "getting genp"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GET_ITAV), "get itav"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ARGS), "invalid args"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_GENP), "invalid genp"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_KEYSPEC), "invalid keyspec"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_OPTION), "invalid option"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ROOTCAKEYUPDATE),
-     "invalid rootcakeyupdate"},
+    "invalid rootcakeyupdate"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_CENTRAL_GEN_KEY),
+     "missing central gen key"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_CERTID), "missing certid"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION),
     "missing key input for creating protection"},
@@ -145,8 +155,12 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     "transactionid unmatched"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNCLEAN_CTX), "unclean ctx"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CENTRAL_GEN_KEY),
+     "unexpected central gen key"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CERTPROFILE),
-     "unexpected certprofile"},
+    "unexpected certprofile"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CRLSTATUSLIST),
+    "unexpected crlstatuslist"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS),
     "unexpected pkistatus"},
@@ -156,6 +170,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID),
     "unknown algorithm id"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CRL_ISSUER), "unknown crl issuer"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_PKISTATUS), "unknown pkistatus"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_ALGORITHM),
     "unsupported algorithm"},

+ 54 - 4
libs/openssl/crypto/cmp/cmp_local.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Nokia 2007-2019
  * Copyright Siemens AG 2015-2019
  *
@@ -211,6 +211,36 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT)
 typedef struct ossl_cmp_rootcakeyupdate_st OSSL_CMP_ROOTCAKEYUPDATE;
 DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE)
 
+typedef struct ossl_cmp_certreqtemplate_st OSSL_CMP_CERTREQTEMPLATE;
+DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTREQTEMPLATE)
+
+/*-
+ * CRLSource ::= CHOICE {
+ *      dpn          [0] DistributionPointName,
+ *      issuer       [1] GeneralNames }
+ */
+
+typedef struct ossl_cmp_crlsource_st {
+    int type;
+    union {
+        DIST_POINT_NAME *dpn;
+        GENERAL_NAMES *issuer;
+    } value;
+} OSSL_CMP_CRLSOURCE;
+DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CRLSOURCE)
+
+/*
+ * CRLStatus ::= SEQUENCE {
+ *      source       CRLSource,
+ *      thisUpdate   Time OPTIONAL }
+ */
+
+struct ossl_cmp_crlstatus_st {
+    OSSL_CMP_CRLSOURCE *source;
+    ASN1_TIME *thisUpdate;
+}; /* OSSL_CMP_CRLSTATUS */
+DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CRLSTATUS)
+
 /*-
  * declared already here as it will be used in OSSL_CMP_MSG (nested) and
  * infoType and infoValue
@@ -264,6 +294,13 @@ struct ossl_cmp_itav_st {
         X509 *rootCaCert;
         /* NID_id_it_rootCaKeyUpdate - Root CA Certificate Update */
         OSSL_CMP_ROOTCAKEYUPDATE *rootCaKeyUpdate;
+        /* NID_id_it_certReqTemplate - Certificate Request Template */
+        OSSL_CMP_CERTREQTEMPLATE *certReqTemplate;
+        /* NID_id_it_crlStatusList -  CRL Update Retrieval */
+        STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList;
+        /* NID_id_it_crls - Certificate Status Lists */
+        STACK_OF(X509_CRL) *crls;
+
         /* this is to be used for so far undeclared objects */
         ASN1_TYPE *other;
     } infoValue;
@@ -274,7 +311,7 @@ typedef struct ossl_cmp_certorenccert_st {
     int type;
     union {
         X509 *certificate;
-        OSSL_CRMF_ENCRYPTEDVALUE *encryptedCert;
+        OSSL_CRMF_ENCRYPTEDKEY *encryptedCert;
     } value;
 } OSSL_CMP_CERTORENCCERT;
 DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTORENCCERT)
@@ -289,7 +326,7 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTORENCCERT)
  */
 typedef struct ossl_cmp_certifiedkeypair_st {
     OSSL_CMP_CERTORENCCERT *certOrEncCert;
-    OSSL_CRMF_ENCRYPTEDVALUE *privateKey;
+    OSSL_CRMF_ENCRYPTEDKEY *privateKey;
     OSSL_CRMF_PKIPUBLICATIONINFO *publicationInfo;
 } OSSL_CMP_CERTIFIEDKEYPAIR;
 DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTIFIEDKEYPAIR)
@@ -765,6 +802,17 @@ struct ossl_cmp_rootcakeyupdate_st {
 } /* OSSL_CMP_ROOTCAKEYUPDATE */;
 DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE)
 
+/*-
+ * CertReqTemplateContent ::= SEQUENCE {
+ *      certTemplate      CertTemplate,
+ *      keySpec           Controls OPTIONAL
+ * }
+ */
+struct ossl_cmp_certreqtemplate_st {
+    OSSL_CRMF_CERTTEMPLATE *certTemplate;
+    OSSL_CMP_ATAVS *keySpec;
+} /* OSSL_CMP_CERTREQTEMPLATE */;
+
 /* from cmp_asn.c */
 int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a);
 
@@ -904,7 +952,8 @@ OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int bodytype,
                                    const OSSL_CRMF_MSG *crm);
 OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype,
                                    int certReqId, const OSSL_CMP_PKISI *si,
-                                   X509 *cert, const X509 *encryption_recip,
+                                   X509 *cert, const EVP_PKEY *pkey,
+                                   const X509 *encryption_recip,
                                    STACK_OF(X509) *chain, STACK_OF(X509) *caPubs,
                                    int unprotectedErrors);
 OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx);
@@ -946,6 +995,7 @@ OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
 int ossl_cmp_is_error_with_waiting(const OSSL_CMP_MSG *msg);
 
 /* from cmp_protect.c */
+void ossl_cmp_set_own_chain(OSSL_CMP_CTX *ctx);
 int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
 ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
                                           const OSSL_CMP_MSG *msg);

+ 2 - 1
libs/openssl/crypto/cms/cms_asn1.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2025 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
@@ -243,6 +243,7 @@ ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
         ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
         ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
 } ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
+IMPLEMENT_ASN1_DUP_FUNCTION(CMS_EnvelopedData)
 
 ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
         ASN1_EMBED(CMS_DigestedData, version, INT32),

+ 8 - 4
libs/openssl/crypto/cms/cms_env.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2025 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
@@ -357,8 +357,12 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
     if (!ossl_cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx))
         return 0;
 
-    X509_up_ref(recip);
-    EVP_PKEY_up_ref(pk);
+    if (!X509_up_ref(recip))
+        return 0;
+    if (!EVP_PKEY_up_ref(pk)) {
+        X509_free(recip);
+        return 0;
+    }
 
     ktri->pkey = pk;
     ktri->recip = recip;
@@ -1301,7 +1305,7 @@ int ossl_cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio)
 
     BIO_get_cipher_ctx(cmsbio, &ctx);
 
-    /* 
+    /*
      * The tag is set only for encryption. There is nothing to do for
      * decryption.
      */

+ 3 - 1
libs/openssl/crypto/cms/cms_kari.c

@@ -405,7 +405,9 @@ int ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri,  X509 *recip,
             return 0;
     }
 
-    EVP_PKEY_up_ref(recipPubKey);
+    if (!EVP_PKEY_up_ref(recipPubKey))
+        return 0;
+
     rek->pkey = recipPubKey;
     return 1;
 }

+ 121 - 22
libs/openssl/crypto/cms/cms_lib.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2025 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
@@ -14,9 +14,12 @@
 #include <openssl/bio.h>
 #include <openssl/asn1.h>
 #include <openssl/cms.h>
+#include <openssl/core_names.h>
 #include "internal/sizes.h"
+#include "internal/cryptlib.h"
 #include "crypto/x509.h"
 #include "cms_local.h"
+#include "internal/cms.h"
 
 static STACK_OF(CMS_CertificateChoices)
 **cms_get0_certificate_choices(CMS_ContentInfo *cms);
@@ -405,6 +408,7 @@ BIO *ossl_cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm,
     const EVP_MD *digest = NULL;
     EVP_MD *fetched_digest = NULL;
     char alg[OSSL_MAX_NAME_SIZE];
+    size_t xof_len = 0;
 
     X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
     OBJ_obj2txt(alg, sizeof(alg), digestoid, 0);
@@ -429,6 +433,24 @@ BIO *ossl_cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm,
         ERR_raise(ERR_LIB_CMS, CMS_R_MD_BIO_INIT_ERROR);
         goto err;
     }
+    if (EVP_MD_xof(digest)) {
+        if (EVP_MD_is_a(digest, SN_shake128))
+            xof_len = 32;
+        else if (EVP_MD_is_a(digest, SN_shake256))
+            xof_len = 64;
+        if (xof_len > 0) {
+            EVP_MD_CTX *mdctx;
+            OSSL_PARAM params[2];
+
+            if (BIO_get_md_ctx(mdbio, &mdctx) <= 0 || mdctx == NULL)
+                goto err;
+            params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN,
+                                                    &xof_len);
+            params[1] = OSSL_PARAM_construct_end();
+            if (!EVP_MD_CTX_set_params(mdctx, params))
+                goto err;
+        }
+    }
     EVP_MD_free(fetched_digest);
     return mdbio;
  err:
@@ -620,52 +642,92 @@ int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
 STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
 {
     STACK_OF(X509) *certs = NULL;
+
+    if (!ossl_cms_get1_certs_ex(cms, &certs))
+        return NULL;
+    if (sk_X509_num(certs) == 0) {
+        sk_X509_free(certs);
+        return NULL;
+    }
+    return certs;
+}
+
+int ossl_cms_get1_certs_ex(CMS_ContentInfo *cms, STACK_OF(X509) **certs)
+{
     CMS_CertificateChoices *cch;
     STACK_OF(CMS_CertificateChoices) **pcerts;
-    int i;
+    int i, n;
 
+    if (certs == NULL)
+        return 0;
+    *certs = NULL;
     pcerts = cms_get0_certificate_choices(cms);
     if (pcerts == NULL)
-        return NULL;
-    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
+        return 0;
+
+    /* make sure to return NULL *certs only on error */
+    n = sk_CMS_CertificateChoices_num(*pcerts);
+    if ((*certs = sk_X509_new_reserve(NULL, n)) == NULL)
+        return 0;
+
+    for (i = 0; i < n; i++) {
         cch = sk_CMS_CertificateChoices_value(*pcerts, i);
         if (cch->type == 0) {
-            if (!ossl_x509_add_cert_new(&certs, cch->d.certificate,
-                                        X509_ADD_FLAG_UP_REF)) {
-                OSSL_STACK_OF_X509_free(certs);
-                return NULL;
+            if (!X509_add_cert(*certs, cch->d.certificate,
+                               X509_ADD_FLAG_UP_REF)) {
+                OSSL_STACK_OF_X509_free(*certs);
+                *certs = NULL;
+                return 0;
             }
         }
     }
-    return certs;
-
+    return 1;
 }
 
 STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
 {
     STACK_OF(X509_CRL) *crls = NULL;
+
+    if (!ossl_cms_get1_crls_ex(cms, &crls))
+        return NULL;
+    if (sk_X509_CRL_num(crls) == 0) {
+        sk_X509_CRL_free(crls);
+        return NULL;
+    }
+    return crls;
+}
+
+int ossl_cms_get1_crls_ex(CMS_ContentInfo *cms, STACK_OF(X509_CRL) **crls)
+{
     STACK_OF(CMS_RevocationInfoChoice) **pcrls;
     CMS_RevocationInfoChoice *rch;
-    int i;
+    int i, n;
 
+    if (crls == NULL)
+        return 0;
+    *crls = NULL;
     pcrls = cms_get0_revocation_choices(cms);
     if (pcrls == NULL)
-        return NULL;
-    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) {
+        return 0;
+
+    /* make sure to return NULL *crls only on error */
+    n = sk_CMS_RevocationInfoChoice_num(*pcrls);
+    if ((*crls = sk_X509_CRL_new_reserve(NULL, n)) == NULL)
+        return 0;
+
+    for (i = 0; i < n; i++) {
         rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
         if (rch->type == 0) {
-            if (crls == NULL) {
-                if ((crls = sk_X509_CRL_new_null()) == NULL)
-                    return NULL;
-            }
-            if (!sk_X509_CRL_push(crls, rch->d.crl)
-                    || !X509_CRL_up_ref(rch->d.crl)) {
-                sk_X509_CRL_pop_free(crls, X509_CRL_free);
-                return NULL;
+            if (!X509_CRL_up_ref(rch->d.crl)
+                || !ossl_assert(sk_X509_CRL_push(*crls, rch->d.crl))) {
+                /* push cannot fail on reserved stack */
+                sk_X509_CRL_pop_free(*crls, X509_CRL_free);
+                *crls = NULL;
+                return 0;
             }
         }
     }
-    return crls;
+    return 1;
 }
 
 int ossl_cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)
@@ -728,3 +790,40 @@ int ossl_cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
     *pkeyid = keyid;
     return 1;
 }
+
+CMS_EnvelopedData *ossl_cms_sign_encrypt(BIO *data, X509 *sign_cert, STACK_OF(X509) *certs,
+                                         EVP_PKEY *sign_key, unsigned int sign_flags,
+                                         STACK_OF(X509) *enc_recip, const EVP_CIPHER *cipher,
+                                         unsigned int enc_flags, OSSL_LIB_CTX *libctx,
+                                         const char *propq)
+{
+    CMS_EnvelopedData *evd = NULL;
+    BIO *privbio = NULL, *signbio = NULL;
+    CMS_ContentInfo *signcms = NULL, *evpcms = NULL;
+
+    if (data == NULL || sign_key == NULL || sign_cert == NULL || enc_recip == NULL) {
+        ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+    signcms = CMS_sign_ex(sign_cert, sign_key, certs, data, sign_flags, libctx, propq);
+    if (signcms == NULL)
+        goto err;
+
+    signbio = BIO_new(BIO_s_mem());
+    if (signbio == NULL
+        || ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_SignedData), signbio, signcms->d.signedData) <= 0)
+        goto err;
+
+    evpcms = CMS_encrypt_ex(enc_recip, signbio, cipher, enc_flags, libctx, propq);
+    if (evpcms == NULL)
+        goto err;
+    evd = CMS_EnvelopedData_dup(evpcms->d.envelopedData);
+
+ err:
+    BIO_free(privbio);
+    BIO_free(signbio);
+    CMS_ContentInfo_free(signcms);
+    CMS_ContentInfo_free(evpcms);
+
+    return evd;
+}

+ 5 - 0
libs/openssl/crypto/cms/cms_local.h

@@ -100,6 +100,8 @@ struct CMS_SignerInfo_st {
     EVP_MD_CTX *mctx;
     EVP_PKEY_CTX *pctx;
     const CMS_CTX *cms_ctx;
+    /* Set to 1 if signing time attribute is to be omitted */
+    int omit_signing_time;
 };
 
 struct CMS_SignerIdentifier_st {
@@ -485,6 +487,9 @@ int ossl_cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt);
 int ossl_cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt);
 int ossl_cms_rsa_sign(CMS_SignerInfo *si, int verify);
 
+int ossl_cms_get1_certs_ex(CMS_ContentInfo *cms, STACK_OF(X509) **certs);
+int ossl_cms_get1_crls_ex(CMS_ContentInfo *cms, STACK_OF(X509_CRL) **crls);
+
 DECLARE_ASN1_ITEM(CMS_CertificateChoices)
 DECLARE_ASN1_ITEM(CMS_DigestedData)
 DECLARE_ASN1_ITEM(CMS_EncryptedData)

+ 52 - 9
libs/openssl/crypto/cms/cms_sd.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2025 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
@@ -225,6 +225,14 @@ int ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
         return -1;
 }
 
+static int cms_signature_nomd(EVP_PKEY *pkey)
+{
+    char def_md[80];
+
+    return EVP_PKEY_get_default_digest_name(pkey, def_md, sizeof(def_md)) == 2
+        && strcmp(def_md, "UNDEF") == 0 ? 1 : 0;
+}
+
 /* Method to map any, incl. provider-implemented PKEY types to OIDs */
 /* (EC)DSA and all provider-delivered signatures implementation is the same */
 static int cms_generic_sign(CMS_SignerInfo *si, int verify)
@@ -249,7 +257,9 @@ static int cms_generic_sign(CMS_SignerInfo *si, int verify)
             if (typename != NULL)
                 pknid = OBJ_txt2nid(typename);
         }
-        if (!OBJ_find_sigid_by_algs(&snid, hnid, pknid))
+        if (pknid > 0 && cms_signature_nomd(pkey))
+            snid = pknid;
+        else if (!OBJ_find_sigid_by_algs(&snid, hnid, pknid))
             return -1;
         return X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, NULL);
     }
@@ -356,14 +366,19 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
     /* Call for side-effect of computing hash and caching extensions */
     X509_check_purpose(signer, -1, -1);
 
-    X509_up_ref(signer);
-    EVP_PKEY_up_ref(pk);
+    if (!X509_up_ref(signer))
+        goto err;
+    if (!EVP_PKEY_up_ref(pk)) {
+        X509_free(signer);
+        goto err;
+    }
 
     si->cms_ctx = ctx;
     si->pkey = pk;
     si->signer = signer;
     si->mctx = EVP_MD_CTX_new();
     si->pctx = NULL;
+    si->omit_signing_time = 0;
 
     if (si->mctx == NULL) {
         ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
@@ -456,6 +471,14 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
                 goto err;
             }
         }
+        if ((flags & CMS_NO_SIGNING_TIME) != 0) {
+            /*
+             * The signing-time signed attribute (NID_pkcs9_signingTime)
+             * would normally be added later, in CMS_SignerInfo_sign(),
+             * unless we set this flag here
+             */
+            si->omit_signing_time = 1;
+        }
         if (flags & CMS_CADES) {
             ESS_SIGNING_CERT *sc = NULL;
             ESS_SIGNING_CERT_V2 *sc2 = NULL;
@@ -624,7 +647,8 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
 void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
 {
     if (signer != NULL) {
-        X509_up_ref(signer);
+        if (!X509_up_ref(signer))
+            return;
         EVP_PKEY_free(si->pkey);
         si->pkey = X509_get_pubkey(signer);
     }
@@ -833,13 +857,15 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
     int alen;
     size_t siglen;
     const CMS_CTX *ctx = si->cms_ctx;
-    char md_name[OSSL_MAX_NAME_SIZE];
+    char md_name_buf[OSSL_MAX_NAME_SIZE], *md_name;
 
-    if (OBJ_obj2txt(md_name, sizeof(md_name),
+    if (OBJ_obj2txt(md_name_buf, sizeof(md_name_buf),
                     si->digestAlgorithm->algorithm, 0) <= 0)
         return 0;
+    md_name = cms_signature_nomd(si->pkey) ? NULL : md_name_buf;
 
-    if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
+    if (!si->omit_signing_time
+        && CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
         if (!cms_add1_signingTime(si, NULL))
             goto err;
     }
@@ -860,9 +886,16 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
         si->pctx = pctx;
     }
 
+    if (md_name == NULL) {
+        if (ASN1_item_sign_ctx(ASN1_ITEM_rptr(CMS_Attributes_Sign), NULL,
+                               NULL, si->signature, si->signedAttrs, mctx) <= 0)
+            goto err;
+        return 1;
+    }
+
     alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
                          ASN1_ITEM_rptr(CMS_Attributes_Sign));
-    if (!abuf)
+    if (alen < 0 || abuf == NULL)
         goto err;
     if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
         goto err;
@@ -907,6 +940,16 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
     if (!ossl_cms_si_check_attributes(si))
         return -1;
 
+    if (cms_signature_nomd(si->pkey)) {
+        r = ASN1_item_verify_ex(ASN1_ITEM_rptr(CMS_Attributes_Sign),
+                                si->signatureAlgorithm, si->signature,
+                                si->signedAttrs, NULL, si->pkey,
+                                libctx, propq);
+        if (r <= 0)
+            ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
+        return r;
+    }
+
     OBJ_obj2txt(name, sizeof(name), si->digestAlgorithm->algorithm, 0);
 
     (void)ERR_set_mark();

+ 59 - 0
libs/openssl/crypto/comp_methods.c

@@ -0,0 +1,59 @@
+/*
+ * Copyright 2024 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/crypto.h>
+#include <openssl/comp.h>
+#include <openssl/obj_mac.h>
+
+#include "internal/cryptlib.h"
+#include "internal/comp.h"
+
+#define SSL_COMP_NULL_IDX       0
+#define SSL_COMP_ZLIB_IDX       1
+#define SSL_COMP_NUM_IDX        2
+
+#ifndef OPENSSL_NO_COMP
+static int sk_comp_cmp(const SSL_COMP *const *a, const SSL_COMP *const *b)
+{
+    return ((*a)->id - (*b)->id);
+}
+#endif
+
+STACK_OF(SSL_COMP) *ossl_load_builtin_compressions(void)
+{
+    STACK_OF(SSL_COMP) *comp_methods = NULL;
+#ifndef OPENSSL_NO_COMP
+    SSL_COMP *comp = NULL;
+    COMP_METHOD *method = COMP_zlib();
+
+    comp_methods = sk_SSL_COMP_new(sk_comp_cmp);
+
+    if (COMP_get_type(method) != NID_undef && comp_methods != NULL) {
+        comp = OPENSSL_malloc(sizeof(*comp));
+        if (comp != NULL) {
+            comp->method = method;
+            comp->id = SSL_COMP_ZLIB_IDX;
+            comp->name = COMP_get_name(method);
+            if (!sk_SSL_COMP_push(comp_methods, comp))
+                OPENSSL_free(comp);
+        }
+    }
+#endif
+    return comp_methods;
+}
+
+static void cmeth_free(SSL_COMP *cm)
+{
+    OPENSSL_free(cm);
+}
+
+void ossl_free_compression_methods_int(STACK_OF(SSL_COMP) *methods)
+{
+    sk_SSL_COMP_pop_free(methods, cmeth_free);
+}

+ 3 - 2
libs/openssl/crypto/conf/conf_lib.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2025 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
@@ -228,7 +228,8 @@ static void collect_section_name(const CONF_VALUE *v, SECTION_NAMES *names)
 {
     /* A section is a CONF_VALUE with name == NULL */
     if (v->name == NULL)
-        sk_OPENSSL_CSTRING_push(names, v->section);
+        /* A failure to push cannot be handled so we ignore the result. */
+        (void)sk_OPENSSL_CSTRING_push(names, v->section);
 }
 
 static int section_name_cmp(OPENSSL_CSTRING const *a, OPENSSL_CSTRING const *b)

+ 26 - 4
libs/openssl/crypto/conf/conf_mod.c

@@ -110,7 +110,17 @@ DEFINE_RUN_ONCE_STATIC(do_init_module_list_lock)
 
 static int conf_diagnostics(const CONF *cnf)
 {
-    return _CONF_get_number(cnf, NULL, "config_diagnostics") != 0;
+    int status;
+    long result = 0;
+
+    ERR_set_mark();
+    status = NCONF_get_number_e(cnf, NULL, "config_diagnostics", &result);
+    ERR_pop_to_mark();
+    if (status > 0) {
+        OSSL_LIB_CTX_set_conf_diagnostics(cnf->libctx, result > 0);
+        return result > 0;
+    }
+    return OSSL_LIB_CTX_get_conf_diagnostics(cnf->libctx);
 }
 
 /* Main function: load modules from a CONF structure */
@@ -183,7 +193,7 @@ int CONF_modules_load_file_ex(OSSL_LIB_CTX *libctx, const char *filename,
 {
     char *file = NULL;
     CONF *conf = NULL;
-    int ret = 0, diagnostics = 0;
+    int ret = 0, diagnostics = OSSL_LIB_CTX_get_conf_diagnostics(libctx);
 
     ERR_set_mark();
 
@@ -213,7 +223,8 @@ int CONF_modules_load_file_ex(OSSL_LIB_CTX *libctx, const char *filename,
     }
 
     ret = CONF_modules_load(conf, appname, flags);
-    diagnostics = conf_diagnostics(conf);
+    /* CONF_modules_load() might change the diagnostics setting, reread it. */
+    diagnostics = OSSL_LIB_CTX_get_conf_diagnostics(libctx);
 
  err:
     if (filename == NULL)
@@ -368,7 +379,6 @@ static CONF_MODULE *module_add(DSO *dso, const char *name,
 
  err:
     ossl_rcu_write_unlock(module_list_lock);
-    sk_CONF_MODULE_free(new_modules);
     if (tmod != NULL) {
         OPENSSL_free(tmod->name);
         OPENSSL_free(tmod);
@@ -682,6 +692,18 @@ char *CONF_get1_default_config_file(void)
         return OPENSSL_strdup(file);
 
     t = X509_get_default_cert_area();
+    /*
+     * On windows systems with -DOSSL_WINCTX set, if the needed registry
+     * keys are not yet set, openssl applets will return, due to an inability
+     * to locate various directories, like the default cert area.  In that
+     * event, clone an empty string here, so that commands like openssl version
+     * continue to operate properly without needing to set OPENSSL_CONF.
+     * Applets like cms will fail gracefully later when they try to parse an
+     * empty config file
+     */
+    if (t == NULL)
+        return OPENSSL_strdup("");
+
 #ifndef OPENSSL_SYS_VMS
     sep = "/";
 #endif

+ 54 - 47
libs/openssl/crypto/context.c

@@ -9,8 +9,10 @@
 
 #include "crypto/cryptlib.h"
 #include <openssl/conf.h>
+#include <openssl/trace.h>
 #include "internal/thread_once.h"
 #include "internal/property.h"
+#include "internal/cryptlib.h"
 #include "internal/core.h"
 #include "internal/bio.h"
 #include "internal/provider.h"
@@ -18,7 +20,7 @@
 #include "crypto/context.h"
 
 struct ossl_lib_ctx_st {
-    CRYPTO_RWLOCK *lock, *rand_crngt_lock;
+    CRYPTO_RWLOCK *lock;
     OSSL_EX_DATA_GLOBAL global;
 
     void *property_string_data;
@@ -39,17 +41,19 @@ struct ossl_lib_ctx_st {
     OSSL_METHOD_STORE *encoder_store;
     OSSL_METHOD_STORE *store_loader_store;
     void *self_test_cb;
+    void *indicator_cb;
 #endif
 #if defined(OPENSSL_THREADS)
     void *threads;
 #endif
-    void *rand_crngt;
 #ifdef FIPS_MODULE
     void *thread_event_handler;
     void *fips_prov;
 #endif
+    STACK_OF(SSL_COMP) *comp_methods;
 
-    unsigned int ischild:1;
+    int ischild;
+    int conf_diagnostics;
 };
 
 int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx)
@@ -95,10 +99,6 @@ static int context_init(OSSL_LIB_CTX *ctx)
     if (ctx->lock == NULL)
         goto err;
 
-    ctx->rand_crngt_lock = CRYPTO_THREAD_lock_new();
-    if (ctx->rand_crngt_lock == NULL)
-        goto err;
-
     /* Initialize ex_data. */
     if (!ossl_do_ex_data_init(ctx))
         goto err;
@@ -108,6 +108,7 @@ static int context_init(OSSL_LIB_CTX *ctx)
     ctx->evp_method_store = ossl_method_store_new(ctx);
     if (ctx->evp_method_store == NULL)
         goto err;
+    OSSL_TRACE1(QUERY, "context_init: allocating store %p\n", ctx->evp_method_store);
 
 #ifndef FIPS_MODULE
     /* P2. Must be freed before the provider store is freed */
@@ -180,6 +181,9 @@ static int context_init(OSSL_LIB_CTX *ctx)
     ctx->self_test_cb = ossl_self_test_set_callback_new(ctx);
     if (ctx->self_test_cb == NULL)
         goto err;
+    ctx->indicator_cb = ossl_indicator_set_callback_new(ctx);
+    if (ctx->indicator_cb == NULL)
+        goto err;
 #endif
 
 #ifdef FIPS_MODULE
@@ -209,6 +213,10 @@ static int context_init(OSSL_LIB_CTX *ctx)
     if (!ossl_property_parse_init(ctx))
         goto err;
 
+#ifndef FIPS_MODULE
+    ctx->comp_methods = ossl_load_builtin_compressions();
+#endif
+
     return 1;
 
  err:
@@ -217,7 +225,6 @@ static int context_init(OSSL_LIB_CTX *ctx)
     if (exdata_done)
         ossl_crypto_cleanup_all_ex_data_int(ctx);
 
-    CRYPTO_THREAD_lock_free(ctx->rand_crngt_lock);
     CRYPTO_THREAD_lock_free(ctx->lock);
     CRYPTO_THREAD_cleanup_local(&ctx->rcu_local_key);
     memset(ctx, '\0', sizeof(*ctx));
@@ -312,17 +319,17 @@ static void context_deinit_objs(OSSL_LIB_CTX *ctx)
     }
 
 #ifndef FIPS_MODULE
+    if (ctx->indicator_cb != NULL) {
+        ossl_indicator_set_callback_free(ctx->indicator_cb);
+        ctx->indicator_cb = NULL;
+    }
+
     if (ctx->self_test_cb != NULL) {
         ossl_self_test_set_callback_free(ctx->self_test_cb);
         ctx->self_test_cb = NULL;
     }
 #endif
 
-    if (ctx->rand_crngt != NULL) {
-        ossl_rand_crng_ctx_free(ctx->rand_crngt);
-        ctx->rand_crngt = NULL;
-    }
-
 #ifdef FIPS_MODULE
     if (ctx->thread_event_handler != NULL) {
         ossl_thread_event_ctx_free(ctx->thread_event_handler);
@@ -349,6 +356,14 @@ static void context_deinit_objs(OSSL_LIB_CTX *ctx)
         ctx->child_provider = NULL;
     }
 #endif
+
+#ifndef FIPS_MODULE
+    if (ctx->comp_methods != NULL) {
+        ossl_free_compression_methods_int(ctx->comp_methods);
+        ctx->comp_methods = NULL;
+    }
+#endif
+
 }
 
 static int context_deinit(OSSL_LIB_CTX *ctx)
@@ -362,9 +377,7 @@ static int context_deinit(OSSL_LIB_CTX *ctx)
 
     ossl_crypto_cleanup_all_ex_data_int(ctx);
 
-    CRYPTO_THREAD_lock_free(ctx->rand_crngt_lock);
     CRYPTO_THREAD_lock_free(ctx->lock);
-    ctx->rand_crngt_lock = NULL;
     ctx->lock = NULL;
     CRYPTO_THREAD_cleanup_local(&ctx->rcu_local_key);
     return 1;
@@ -555,8 +568,6 @@ int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX *ctx)
 
 void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index)
 {
-    void *p;
-
     ctx = ossl_lib_ctx_get_concrete(ctx);
     if (ctx == NULL)
         return NULL;
@@ -595,42 +606,14 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index)
         return ctx->store_loader_store;
     case OSSL_LIB_CTX_SELF_TEST_CB_INDEX:
         return ctx->self_test_cb;
+    case OSSL_LIB_CTX_INDICATOR_CB_INDEX:
+        return ctx->indicator_cb;
 #endif
 #ifndef OPENSSL_NO_THREAD_POOL
     case OSSL_LIB_CTX_THREAD_INDEX:
         return ctx->threads;
 #endif
 
-    case OSSL_LIB_CTX_RAND_CRNGT_INDEX: {
-
-        /*
-         * rand_crngt must be lazily initialized because it calls into
-         * libctx, so must not be called from context_init, else a deadlock
-         * will occur.
-         *
-         * We use a separate lock because code called by the instantiation
-         * of rand_crngt is liable to try and take the libctx lock.
-         */
-        if (CRYPTO_THREAD_read_lock(ctx->rand_crngt_lock) != 1)
-            return NULL;
-
-        if (ctx->rand_crngt == NULL) {
-            CRYPTO_THREAD_unlock(ctx->rand_crngt_lock);
-
-            if (CRYPTO_THREAD_write_lock(ctx->rand_crngt_lock) != 1)
-                return NULL;
-
-            if (ctx->rand_crngt == NULL)
-                ctx->rand_crngt = ossl_rand_crng_ctx_new(ctx);
-        }
-
-        p = ctx->rand_crngt;
-
-        CRYPTO_THREAD_unlock(ctx->rand_crngt_lock);
-
-        return p;
-    }
-
 #ifdef FIPS_MODULE
     case OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX:
         return ctx->thread_event_handler;
@@ -639,11 +622,19 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index)
         return ctx->fips_prov;
 #endif
 
+    case OSSL_LIB_CTX_COMP_METHODS:
+        return (void *)&ctx->comp_methods;
+
     default:
         return NULL;
     }
 }
 
+void *OSSL_LIB_CTX_get_data(OSSL_LIB_CTX *ctx, int index)
+{
+    return ossl_lib_ctx_get_data(ctx, index);
+}
+
 OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx)
 {
     ctx = ossl_lib_ctx_get_concrete(ctx);
@@ -672,3 +663,19 @@ CRYPTO_THREAD_LOCAL *ossl_lib_ctx_get_rcukey(OSSL_LIB_CTX *libctx)
         return NULL;
     return &libctx->rcu_local_key;
 }
+
+int OSSL_LIB_CTX_get_conf_diagnostics(OSSL_LIB_CTX *libctx)
+{
+    libctx = ossl_lib_ctx_get_concrete(libctx);
+    if (libctx == NULL)
+        return 0;
+    return libctx->conf_diagnostics;
+}
+
+void OSSL_LIB_CTX_set_conf_diagnostics(OSSL_LIB_CTX *libctx, int value)
+{
+    libctx = ossl_lib_ctx_get_concrete(libctx);
+    if (libctx == NULL)
+        return;
+    libctx->conf_diagnostics = value;
+}

+ 5 - 1
libs/openssl/crypto/core_fetch.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -10,6 +10,7 @@
 #include <stddef.h>
 
 #include <openssl/core.h>
+#include <openssl/trace.h>
 #include "internal/cryptlib.h"
 #include "internal/core.h"
 #include "internal/property.h"
@@ -110,6 +111,9 @@ static void ossl_method_construct_this(OSSL_PROVIDER *provider,
         == NULL)
         return;
 
+    OSSL_TRACE2(QUERY,
+                "ossl_method_construct_this: putting an algo to the store %p with no_store %d\n",
+                (void *)data->store, no_store);
     /*
      * Note regarding putting the method in stores:
      *

+ 155 - 132
libs/openssl/crypto/core_namemap.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -8,62 +8,53 @@
  */
 
 #include "internal/namemap.h"
-#include <openssl/lhash.h>
-#include "crypto/lhash.h"      /* ossl_lh_strcasehash */
 #include "internal/tsan_assist.h"
+#include "internal/hashtable.h"
 #include "internal/sizes.h"
 #include "crypto/context.h"
 
-/*-
- * The namenum entry
- * =================
- */
-typedef struct {
-    char *name;
-    int number;
-} NAMENUM_ENTRY;
+#define NAMEMAP_HT_BUCKETS 512
 
-DEFINE_LHASH_OF_EX(NAMENUM_ENTRY);
+HT_START_KEY_DEFN(namenum_key)
+HT_DEF_KEY_FIELD_CHAR_ARRAY(name, 64)
+HT_END_KEY_DEFN(NAMENUM_KEY)
 
 /*-
  * The namemap itself
  * ==================
  */
 
+typedef STACK_OF(OPENSSL_STRING) NAMES;
+
+DEFINE_STACK_OF(NAMES)
+
 struct ossl_namemap_st {
     /* Flags */
     unsigned int stored:1; /* If 1, it's stored in a library context */
 
+    HT *namenum_ht;        /* Name->number mapping */
+
     CRYPTO_RWLOCK *lock;
-    LHASH_OF(NAMENUM_ENTRY) *namenum;  /* Name->number mapping */
+    STACK_OF(NAMES) *numnames;
 
     TSAN_QUALIFIER int max_number;     /* Current max number */
 };
 
-/* LHASH callbacks */
-
-static unsigned long namenum_hash(const NAMENUM_ENTRY *n)
+static void name_string_free(char *name)
 {
-    return ossl_lh_strcasehash(n->name);
+    OPENSSL_free(name);
 }
 
-static int namenum_cmp(const NAMENUM_ENTRY *a, const NAMENUM_ENTRY *b)
+static void names_free(NAMES *n)
 {
-    return OPENSSL_strcasecmp(a->name, b->name);
-}
-
-static void namenum_free(NAMENUM_ENTRY *n)
-{
-    if (n != NULL)
-        OPENSSL_free(n->name);
-    OPENSSL_free(n);
+    sk_OPENSSL_STRING_pop_free(n, name_string_free);
 }
 
 /* OSSL_LIB_CTX_METHOD functions for a namemap stored in a library context */
 
 void *ossl_stored_namemap_new(OSSL_LIB_CTX *libctx)
 {
-    OSSL_NAMEMAP *namemap = ossl_namemap_new();
+    OSSL_NAMEMAP *namemap = ossl_namemap_new(libctx);
 
     if (namemap != NULL)
         namemap->stored = 1;
@@ -107,20 +98,6 @@ int ossl_namemap_empty(OSSL_NAMEMAP *namemap)
 #endif
 }
 
-typedef struct doall_names_data_st {
-    int number;
-    const char **names;
-    int found;
-} DOALL_NAMES_DATA;
-
-static void do_name(const NAMENUM_ENTRY *namenum, DOALL_NAMES_DATA *data)
-{
-    if (namenum->number == data->number)
-        data->names[data->found++] = namenum->name;
-}
-
-IMPLEMENT_LHASH_DOALL_ARG_CONST(NAMENUM_ENTRY, DOALL_NAMES_DATA);
-
 /*
  * Call the callback for all names in the namemap with the given number.
  * A return value 1 means that the callback was called for all names. A
@@ -130,61 +107,41 @@ int ossl_namemap_doall_names(const OSSL_NAMEMAP *namemap, int number,
                              void (*fn)(const char *name, void *data),
                              void *data)
 {
-    DOALL_NAMES_DATA cbdata;
-    size_t num_names;
     int i;
+    NAMES *names;
 
-    cbdata.number = number;
-    cbdata.found = 0;
-
-    if (namemap == NULL)
+    if (namemap == NULL || number <= 0)
         return 0;
 
     /*
-     * We collect all the names first under a read lock. Subsequently we call
+     * We duplicate the NAMES stack under a read lock. Subsequently we call
      * the user function, so that we're not holding the read lock when in user
      * code. This could lead to deadlocks.
      */
     if (!CRYPTO_THREAD_read_lock(namemap->lock))
         return 0;
 
-    num_names = lh_NAMENUM_ENTRY_num_items(namemap->namenum);
-    if (num_names == 0) {
-        CRYPTO_THREAD_unlock(namemap->lock);
-        return 0;
-    }
-    cbdata.names = OPENSSL_malloc(sizeof(*cbdata.names) * num_names);
-    if (cbdata.names == NULL) {
-        CRYPTO_THREAD_unlock(namemap->lock);
-        return 0;
-    }
-    lh_NAMENUM_ENTRY_doall_DOALL_NAMES_DATA(namemap->namenum, do_name,
-                                            &cbdata);
+    names = sk_NAMES_value(namemap->numnames, number - 1);
+    if (names != NULL)
+        names = sk_OPENSSL_STRING_dup(names);
+
     CRYPTO_THREAD_unlock(namemap->lock);
 
-    for (i = 0; i < cbdata.found; i++)
-        fn(cbdata.names[i], data);
+    if (names == NULL)
+        return 0;
 
-    OPENSSL_free(cbdata.names);
-    return 1;
-}
+    for (i = 0; i < sk_OPENSSL_STRING_num(names); i++)
+        fn(sk_OPENSSL_STRING_value(names, i), data);
 
-/* This function is not thread safe, the namemap must be locked */
-static int namemap_name2num(const OSSL_NAMEMAP *namemap,
-                            const char *name)
-{
-    NAMENUM_ENTRY *namenum_entry, namenum_tmpl;
-
-    namenum_tmpl.name = (char *)name;
-    namenum_tmpl.number = 0;
-    namenum_entry =
-        lh_NAMENUM_ENTRY_retrieve(namemap->namenum, &namenum_tmpl);
-    return namenum_entry != NULL ? namenum_entry->number : 0;
+    sk_OPENSSL_STRING_free(names);
+    return i > 0;
 }
 
 int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name)
 {
-    int number;
+    int number = 0;
+    HT_VALUE *val;
+    NAMENUM_KEY key;
 
 #ifndef FIPS_MODULE
     if (namemap == NULL)
@@ -194,10 +151,14 @@ int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name)
     if (namemap == NULL)
         return 0;
 
-    if (!CRYPTO_THREAD_read_lock(namemap->lock))
-        return 0;
-    number = namemap_name2num(namemap, name);
-    CRYPTO_THREAD_unlock(namemap->lock);
+    HT_INIT_KEY(&key);
+    HT_SET_KEY_STRING_CASE(&key, name, name);
+
+    val = ossl_ht_get(namemap->namenum_ht, TO_HT_KEY(&key));
+
+    if (val != NULL)
+        /* We store a (small) int directly instead of a pointer to it. */
+        number = (int)(intptr_t)val->value;
 
     return number;
 }
@@ -205,73 +166,122 @@ int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name)
 int ossl_namemap_name2num_n(const OSSL_NAMEMAP *namemap,
                             const char *name, size_t name_len)
 {
-    char *tmp;
-    int ret;
+    int number = 0;
+    HT_VALUE *val;
+    NAMENUM_KEY key;
 
-    if (name == NULL || (tmp = OPENSSL_strndup(name, name_len)) == NULL)
+#ifndef FIPS_MODULE
+    if (namemap == NULL)
+        namemap = ossl_namemap_stored(NULL);
+#endif
+
+    if (namemap == NULL)
         return 0;
 
-    ret = ossl_namemap_name2num(namemap, tmp);
-    OPENSSL_free(tmp);
-    return ret;
-}
+    HT_INIT_KEY(&key);
+    HT_SET_KEY_STRING_CASE_N(&key, name, name, name_len);
 
-struct num2name_data_st {
-    size_t idx;                  /* Countdown */
-    const char *name;            /* Result */
-};
+    val = ossl_ht_get(namemap->namenum_ht, TO_HT_KEY(&key));
 
-static void do_num2name(const char *name, void *vdata)
-{
-    struct num2name_data_st *data = vdata;
+    if (val != NULL)
+        /* We store a (small) int directly instead of a pointer to it. */
+        number = (int)(intptr_t)val->value;
 
-    if (data->idx > 0)
-        data->idx--;
-    else if (data->name == NULL)
-        data->name = name;
+    return number;
 }
 
 const char *ossl_namemap_num2name(const OSSL_NAMEMAP *namemap, int number,
                                   size_t idx)
 {
-    struct num2name_data_st data;
+    NAMES *names;
+    const char *ret = NULL;
+
+    if (namemap == NULL || number <= 0)
+        return NULL;
 
-    data.idx = idx;
-    data.name = NULL;
-    if (!ossl_namemap_doall_names(namemap, number, do_num2name, &data))
+    if (!CRYPTO_THREAD_read_lock(namemap->lock))
         return NULL;
-    return data.name;
+
+    names = sk_NAMES_value(namemap->numnames, number - 1);
+    if (names != NULL)
+        ret = sk_OPENSSL_STRING_value(names, idx);
+
+    CRYPTO_THREAD_unlock(namemap->lock);
+
+    return ret;
+}
+
+/* This function is not thread safe, the namemap must be locked */
+static int numname_insert(OSSL_NAMEMAP *namemap, int number,
+                          const char *name)
+{
+    NAMES *names;
+    char *tmpname;
+
+    if (number > 0) {
+        names = sk_NAMES_value(namemap->numnames, number - 1);
+        if (!ossl_assert(names != NULL)) {
+            /* cannot happen */
+            return 0;
+        }
+    } else {
+        /* a completely new entry */
+        names = sk_OPENSSL_STRING_new_null();
+        if (names == NULL)
+            return 0;
+    }
+
+    if ((tmpname = OPENSSL_strdup(name)) == NULL)
+        goto err;
+
+    if (!sk_OPENSSL_STRING_push(names, tmpname))
+        goto err;
+    tmpname = NULL;
+
+    if (number <= 0) {
+        if (!sk_NAMES_push(namemap->numnames, names))
+            goto err;
+        number = sk_NAMES_num(namemap->numnames);
+    }
+    return number;
+
+ err:
+    if (number <= 0)
+        sk_OPENSSL_STRING_pop_free(names, name_string_free);
+    OPENSSL_free(tmpname);
+    return 0;
 }
 
 /* This function is not thread safe, the namemap must be locked */
 static int namemap_add_name(OSSL_NAMEMAP *namemap, int number,
                             const char *name)
 {
-    NAMENUM_ENTRY *namenum = NULL;
-    int tmp_number;
+    int ret;
+    HT_VALUE val = { 0 };
+    NAMENUM_KEY key;
 
     /* If it already exists, we don't add it */
-    if ((tmp_number = namemap_name2num(namemap, name)) != 0)
-        return tmp_number;
+    if ((ret = ossl_namemap_name2num(namemap, name)) != 0)
+        return ret;
 
-    if ((namenum = OPENSSL_zalloc(sizeof(*namenum))) == NULL)
+    if ((number = numname_insert(namemap, number, name)) == 0)
         return 0;
 
-    if ((namenum->name = OPENSSL_strdup(name)) == NULL)
-        goto err;
-
-    /* The tsan_counter use here is safe since we're under lock */
-    namenum->number =
-        number != 0 ? number : 1 + tsan_counter(&namemap->max_number);
-    (void)lh_NAMENUM_ENTRY_insert(namemap->namenum, namenum);
+    /* Using tsan_store alone here is safe since we're under lock */
+    tsan_store(&namemap->max_number, number);
 
-    if (lh_NAMENUM_ENTRY_error(namemap->namenum))
-        goto err;
-    return namenum->number;
-
- err:
-    namenum_free(namenum);
-    return 0;
+    HT_INIT_KEY(&key);
+    HT_SET_KEY_STRING_CASE(&key, name, name);
+    val.value = (void *)(intptr_t)number;
+    ret = ossl_ht_insert(namemap->namenum_ht, TO_HT_KEY(&key), &val, NULL);
+    if (!ossl_assert(ret != 0)) /* cannot happen as we are under write lock */
+        return 0;
+    if (ret < 1) {
+        /* unable to insert due to too many collisions */
+        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_NAMES);
+        return 0;
+    }
+    return number;
 }
 
 int ossl_namemap_add_name(OSSL_NAMEMAP *namemap, int number,
@@ -334,7 +344,7 @@ int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number,
             goto end;
         }
 
-        this_number = namemap_name2num(namemap, p);
+        this_number = ossl_namemap_name2num(namemap, p);
 
         if (number == 0) {
             number = this_number;
@@ -508,16 +518,28 @@ OSSL_NAMEMAP *ossl_namemap_stored(OSSL_LIB_CTX *libctx)
     return namemap;
 }
 
-OSSL_NAMEMAP *ossl_namemap_new(void)
+OSSL_NAMEMAP *ossl_namemap_new(OSSL_LIB_CTX *libctx)
 {
     OSSL_NAMEMAP *namemap;
+    HT_CONFIG htconf = { NULL, NULL, NULL, NAMEMAP_HT_BUCKETS, 1, 1 };
 
-    if ((namemap = OPENSSL_zalloc(sizeof(*namemap))) != NULL
-        && (namemap->lock = CRYPTO_THREAD_lock_new()) != NULL
-        && (namemap->namenum =
-            lh_NAMENUM_ENTRY_new(namenum_hash, namenum_cmp)) != NULL)
-        return namemap;
+    htconf.ctx = libctx;
 
+    if ((namemap = OPENSSL_zalloc(sizeof(*namemap))) == NULL)
+        goto err;
+
+    if ((namemap->lock = CRYPTO_THREAD_lock_new()) == NULL)
+        goto err;
+
+    if ((namemap->namenum_ht = ossl_ht_new(&htconf)) == NULL)
+        goto err;
+
+    if ((namemap->numnames = sk_NAMES_new_null()) == NULL)
+        goto err;
+
+    return namemap;
+
+ err:
     ossl_namemap_free(namemap);
     return NULL;
 }
@@ -527,8 +549,9 @@ void ossl_namemap_free(OSSL_NAMEMAP *namemap)
     if (namemap == NULL || namemap->stored)
         return;
 
-    lh_NAMENUM_ENTRY_doall(namemap->namenum, namenum_free);
-    lh_NAMENUM_ENTRY_free(namemap->namenum);
+    sk_NAMES_pop_free(namemap->numnames, names_free);
+
+    ossl_ht_free(namemap->namenum_ht);
 
     CRYPTO_THREAD_lock_free(namemap->lock);
     OPENSSL_free(namemap);

+ 2 - 1
libs/openssl/crypto/cpt_err.c

@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -65,6 +65,7 @@ static const ERR_STRING_DATA CRYPTO_str_reasons[] = {
     "secure malloc failure"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_STRING_TOO_LONG), "string too long"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_BYTES), "too many bytes"},
+    {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_NAMES), "too many names"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_RECORDS),
     "too many records"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_SMALL_BUFFER),

+ 35 - 20
libs/openssl/crypto/cpuid.c

@@ -14,7 +14,7 @@
         defined(__x86_64) || defined(__x86_64__) || \
         defined(_M_AMD64) || defined(_M_X64)
 
-extern unsigned int OPENSSL_ia32cap_P[4];
+extern unsigned int OPENSSL_ia32cap_P[OPENSSL_IA32CAP_P_MAX_INDEXES];
 
 # if defined(OPENSSL_CPUID_OBJ)
 
@@ -29,7 +29,7 @@ extern unsigned int OPENSSL_ia32cap_P[4];
  */
 #  ifdef _WIN32
 typedef WCHAR variant_char;
-
+#   define OPENSSL_IA32CAP_P_MAX_CHAR_SIZE 256
 static variant_char *ossl_getenv(const char *name)
 {
     /*
@@ -37,10 +37,10 @@ static variant_char *ossl_getenv(const char *name)
      * just ignore |name| and use equivalent wide-char L-literal.
      * As well as to ignore excessively long values...
      */
-    static WCHAR value[48];
-    DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, 48);
+    static WCHAR value[OPENSSL_IA32CAP_P_MAX_CHAR_SIZE];
+    DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, OPENSSL_IA32CAP_P_MAX_CHAR_SIZE);
 
-    return (len > 0 && len < 48) ? value : NULL;
+    return (len > 0 && len < OPENSSL_IA32CAP_P_MAX_CHAR_SIZE) ? value : NULL;
 }
 #  else
 typedef char variant_char;
@@ -98,6 +98,7 @@ void OPENSSL_cpuid_setup(void)
     IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
     IA32CAP vec;
     const variant_char *env;
+    int index = 2;
 
     if (trigger)
         return;
@@ -126,23 +127,37 @@ void OPENSSL_cpuid_setup(void)
             vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
         }
 
-        if ((env = ossl_strchr(env, ':')) != NULL) {
-            IA32CAP vecx;
-
+        /* Processed indexes 0, 1 */
+        if ((env = ossl_strchr(env, ':')) != NULL)
             env++;
-            off = (env[0] == '~') ? 1 : 0;
-            vecx = ossl_strtouint64(env + off);
-            if (off) {
-                OPENSSL_ia32cap_P[2] &= ~(unsigned int)vecx;
-                OPENSSL_ia32cap_P[3] &= ~(unsigned int)(vecx >> 32);
-            } else {
-                OPENSSL_ia32cap_P[2] = (unsigned int)vecx;
-                OPENSSL_ia32cap_P[3] = (unsigned int)(vecx >> 32);
+        for (; index < OPENSSL_IA32CAP_P_MAX_INDEXES; index += 2) {
+            if ((env != NULL) && (env[0] != '\0')) {
+                /* if env[0] == ':' current index is skipped */
+                if (env[0] != ':') {
+                    IA32CAP vecx;
+
+                    off = (env[0] == '~') ? 1 : 0;
+                    vecx = ossl_strtouint64(env + off);
+                    if (off) {
+                        OPENSSL_ia32cap_P[index] &= ~(unsigned int)vecx;
+                        OPENSSL_ia32cap_P[index + 1] &= ~(unsigned int)(vecx >> 32);
+                    } else {
+                        OPENSSL_ia32cap_P[index] = (unsigned int)vecx;
+                        OPENSSL_ia32cap_P[index + 1] = (unsigned int)(vecx >> 32);
+                    }
+                }
+                /* skip delimeter */
+                if ((env = ossl_strchr(env, ':')) != NULL)
+                    env++;
+            } else { /* zeroize the next two indexes */
+                OPENSSL_ia32cap_P[index] = 0;
+                OPENSSL_ia32cap_P[index + 1] = 0;
             }
-        } else {
-            OPENSSL_ia32cap_P[2] = 0;
-            OPENSSL_ia32cap_P[3] = 0;
         }
+
+        /* If AVX10 is disabled, zero out its detailed cap bits */
+        if (!(OPENSSL_ia32cap_P[6] & (1 << 19)))
+            OPENSSL_ia32cap_P[9] = 0;
     } else {
         vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
     }
@@ -156,7 +171,7 @@ void OPENSSL_cpuid_setup(void)
     OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
 }
 # else
-unsigned int OPENSSL_ia32cap_P[4];
+unsigned int OPENSSL_ia32cap_P[OPENSSL_IA32CAP_P_MAX_INDEXES];
 # endif
 #endif
 

+ 31 - 18
libs/openssl/crypto/crmf/crmf_err.c

@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -18,44 +18,57 @@
 
 static const ERR_STRING_DATA CRMF_str_reasons[] = {
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_BAD_PBM_ITERATIONCOUNT),
-    "bad pbm iterationcount"},
+     "bad pbm iterationcount"},
+    {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_CMS_NOT_SUPPORTED), "cms not supported"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_CRMFERROR), "crmferror"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR), "error"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECODING_CERTIFICATE),
-    "error decoding certificate"},
+     "error decoding certificate"},
+    {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECODING_ENCRYPTEDKEY),
+     "error decoding encryptedkey"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_CERTIFICATE),
-    "error decrypting certificate"},
+     "error decrypting certificate"},
+    {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_ENCRYPTEDKEY),
+     "error decrypting encryptedkey"},
+    {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_ENCRYPTEDVALUE),
+     "error decrypting encryptedvalue"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY),
-    "error decrypting symmetric key"},
+     "error decrypting symmetric key"},
+    {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_SETTING_PURPOSE),
+     "error setting purpose"},
+    {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_VERIFYING_ENCRYPTEDKEY),
+     "error verifying encryptedkey"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_FAILURE_OBTAINING_RANDOM),
-    "failure obtaining random"},
+     "failure obtaining random"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ITERATIONCOUNT_BELOW_100),
-    "iterationcount below 100"},
+     "iterationcount below 100"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED),
-    "poposkinput not supported"},
+     "poposkinput not supported"},
+    {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_CENTRAL_KEYGEN),
+     "popo inconsistent central keygen"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY),
-    "popo inconsistent public key"},
+     "popo inconsistent public key"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING), "popo missing"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_PUBLIC_KEY),
-    "popo missing public key"},
+     "popo missing public key"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_SUBJECT),
-    "popo missing subject"},
+     "popo missing subject"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED),
-    "popo raverified not accepted"},
+     "popo raverified not accepted"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_MAC_ALGOR_FAILURE),
-    "setting mac algor failure"},
+     "setting mac algor failure"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_OWF_ALGOR_FAILURE),
-    "setting owf algor failure"},
+     "setting owf algor failure"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALGORITHM),
-    "unsupported algorithm"},
+     "unsupported algorithm"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_CIPHER),
-    "unsupported cipher"},
+     "unsupported cipher"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO),
-    "unsupported method for creating popo"},
+     "unsupported method for creating popo"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_METHOD),
-    "unsupported popo method"},
+     "unsupported popo method"},
     {0, NULL}
 };
 

+ 22 - 32
libs/openssl/crypto/crmf/crmf_local.h

@@ -1,5 +1,5 @@
 /*-
- * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Nokia 2007-2019
  * Copyright Siemens AG 2015-2019
  *
@@ -15,7 +15,9 @@
 # define OSSL_CRYPTO_CRMF_LOCAL_H
 
 # include <openssl/crmf.h>
+# include <openssl/cms.h> /* for CMS_EnvelopedData and CMS_SignedData */
 # include <openssl/err.h>
+# include "internal/crmf.h" /* for ossl_crmf_attributetypeandvalue_st */
 
 /* explicit #includes not strictly needed since implied by the above: */
 # include <openssl/types.h>
@@ -51,6 +53,25 @@ struct ossl_crmf_encryptedvalue_st {
     ASN1_BIT_STRING *encValue;
 } /* OSSL_CRMF_ENCRYPTEDVALUE */;
 
+/*
+ *    EncryptedKey ::= CHOICE {
+ *       encryptedValue        EncryptedValue, -- Deprecated
+ *       envelopedData     [0] EnvelopedData }
+ *       -- The encrypted private key MUST be placed in the envelopedData
+ *       -- encryptedContentInfo encryptedContent OCTET STRING.
+ */
+# define OSSL_CRMF_ENCRYPTEDKEY_ENVELOPEDDATA 1
+
+struct ossl_crmf_encryptedkey_st {
+    int type;
+    union {
+        OSSL_CRMF_ENCRYPTEDVALUE *encryptedValue; /* 0 */ /* Deprecated */
+# ifndef OPENSSL_NO_CMS
+        CMS_EnvelopedData *envelopedData; /* 1 */
+# endif
+    } value;
+} /* OSSL_CRMF_ENCRYPTEDKEY */;
+
 /*-
  *  Attributes ::= SET OF Attribute
  *  => X509_ATTRIBUTE
@@ -335,37 +356,6 @@ struct ossl_crmf_certrequest_st {
 DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTREQUEST)
 DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTREQUEST)
 
-struct ossl_crmf_attributetypeandvalue_st {
-    ASN1_OBJECT *type;
-    union {
-        /* NID_id_regCtrl_regToken */
-        ASN1_UTF8STRING *regToken;
-
-        /* NID_id_regCtrl_authenticator */
-        ASN1_UTF8STRING *authenticator;
-
-        /* NID_id_regCtrl_pkiPublicationInfo */
-        OSSL_CRMF_PKIPUBLICATIONINFO *pkiPublicationInfo;
-
-        /* NID_id_regCtrl_oldCertID */
-        OSSL_CRMF_CERTID *oldCertID;
-
-        /* NID_id_regCtrl_protocolEncrKey */
-        X509_PUBKEY *protocolEncrKey;
-
-        /* NID_id_regInfo_utf8Pairs */
-        ASN1_UTF8STRING *utf8Pairs;
-
-        /* NID_id_regInfo_certReq */
-        OSSL_CRMF_CERTREQUEST *certReq;
-
-        ASN1_TYPE *other;
-    } value;
-} /* OSSL_CRMF_ATTRIBUTETYPEANDVALUE */;
-DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
-DEFINE_STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
-DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE)
-
 /*-
  * CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg
  * CertReqMsg ::= SEQUENCE {

+ 204 - 0
libs/openssl/crypto/defaults.c

@@ -0,0 +1,204 @@
+/*
+ * Copyright 1995-2025 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <openssl/opensslv.h>
+#include "internal/thread_once.h"
+#include "internal/cryptlib.h"
+#include "internal/e_os.h"
+
+#if defined(_WIN32) && defined(OSSL_WINCTX)
+
+# define TOSTR(x) #x
+# define MAKESTR(x) TOSTR(x)
+# define NOQUOTE(x) x
+# if defined(OSSL_WINCTX)
+#  define REGISTRY_KEY "SOFTWARE\\WOW6432Node\\OpenSSL" "-" MAKESTR(OPENSSL_VERSION_MAJOR) "." MAKESTR(OPENSSL_VERSION_MINOR) "-" MAKESTR(OSSL_WINCTX)
+# endif
+
+/**
+ * @brief The directory where OpenSSL is installed.
+ */
+static char openssldir[MAX_PATH + 1];
+
+/**
+ * @brief The pointer to the openssldir buffer
+ */
+static char *openssldirptr = NULL;
+
+/**
+ * @brief The directory where OpenSSL engines are located.
+ */
+
+static char enginesdir[MAX_PATH + 1];
+
+/**
+ * @brief The pointer to the enginesdir buffer
+ */
+static char *enginesdirptr = NULL;
+
+/**
+ * @brief The directory where OpenSSL modules are located.
+ */
+static char modulesdir[MAX_PATH + 1];
+
+/**
+ * @brief The pointer to the modulesdir buffer
+ */
+static char *modulesdirptr = NULL;
+
+/**
+ * @brief Get the list of Windows registry directories.
+ *
+ * This function retrieves a list of Windows registry directories.
+ *
+ * @return A pointer to a char array containing the registry directories.
+ */
+static char *get_windows_regdirs(char *dst, DWORD dstsizebytes, LPCWSTR valuename)
+{
+    char *retval = NULL;
+# ifdef REGISTRY_KEY
+    DWORD keysizebytes;
+    DWORD ktype;
+    HKEY hkey;
+    LSTATUS ret;
+    DWORD index = 0;
+    LPCWSTR tempstr = NULL;
+
+    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                       TEXT(REGISTRY_KEY), KEY_WOW64_32KEY,
+                       KEY_QUERY_VALUE, &hkey);
+    if (ret != ERROR_SUCCESS)
+        goto out;
+
+    /* Always use wide call so we can avoid extra encoding conversions on the output */
+    ret = RegQueryValueExW(hkey, valuename, NULL, &ktype, NULL,
+                           &keysizebytes);
+    if (ret != ERROR_SUCCESS)
+        goto out;
+    if (ktype != REG_EXPAND_SZ && ktype != REG_SZ)
+        goto out;
+    if (keysizebytes > MAX_PATH * sizeof(WCHAR))
+        goto out;
+
+    /*
+     * RegQueryValueExW does not guarantee the buffer is null terminated,
+     * so we make space for one in the allocation
+     */
+    tempstr = OPENSSL_zalloc(keysizebytes + sizeof(WCHAR));
+
+    if (tempstr == NULL)
+        goto out;
+
+    if (RegQueryValueExW(hkey, valuename,
+                         NULL, &ktype, (LPBYTE)tempstr, &keysizebytes) != ERROR_SUCCESS)
+        goto out;
+
+    if (!WideCharToMultiByte(CP_UTF8, 0, tempstr, -1, dst, dstsizebytes,
+                             NULL, NULL))
+        goto out;
+
+    retval = dst;
+out:
+    OPENSSL_free(tempstr);
+    RegCloseKey(hkey);
+# endif /* REGISTRY_KEY */
+    return retval;
+}
+
+static CRYPTO_ONCE defaults_setup_init = CRYPTO_ONCE_STATIC_INIT;
+
+/**
+ * @brief Function to setup default values to run once.
+ * Only used in Windows environments.  Does run time initialization
+ * of openssldir/modulesdir/enginesdir from the registry
+ */
+DEFINE_RUN_ONCE_STATIC(do_defaults_setup)
+{
+    get_windows_regdirs(openssldir, sizeof(openssldir), L"OPENSSLDIR");
+    get_windows_regdirs(enginesdir, sizeof(enginesdir), L"ENGINESDIR");
+    get_windows_regdirs(modulesdir, sizeof(modulesdir), L"MODULESDIR");
+
+    /*
+     * Set our pointers only if the directories are fetched properly
+     */
+    if (strlen(openssldir) > 0)
+        openssldirptr = openssldir;
+
+    if (strlen(enginesdir) > 0)
+        enginesdirptr = enginesdir;
+
+    if (strlen(modulesdir) > 0)
+        modulesdirptr = modulesdir;
+
+    return 1;
+}
+#endif /* defined(_WIN32) && defined(OSSL_WINCTX) */
+
+/**
+ * @brief Get the directory where OpenSSL is installed.
+ *
+ * @return A pointer to a string containing the OpenSSL directory path.
+ */
+const char *ossl_get_openssldir(void)
+{
+#if defined(_WIN32) && defined (OSSL_WINCTX)
+    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
+        return NULL;
+    return (const char *)openssldirptr;
+# else
+    return OPENSSLDIR;
+#endif
+}
+
+/**
+ * @brief Get the directory where OpenSSL engines are located.
+ *
+ * @return A pointer to a string containing the engines directory path.
+ */
+const char *ossl_get_enginesdir(void)
+{
+#if defined(_WIN32) && defined (OSSL_WINCTX)
+    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
+        return NULL;
+    return (const char *)enginesdirptr;
+#else
+    return ENGINESDIR;
+#endif
+}
+
+/**
+ * @brief Get the directory where OpenSSL modules are located.
+ *
+ * @return A pointer to a string containing the modules directory path.
+ */
+const char *ossl_get_modulesdir(void)
+{
+#if defined(_WIN32) && defined(OSSL_WINCTX)
+    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
+        return NULL;
+    return (const char *)modulesdirptr;
+#else
+    return MODULESDIR;
+#endif
+}
+
+/**
+ * @brief Get the build time defined windows installer context
+ *
+ * @return A char pointer to a string representing the windows install context
+ */
+const char *ossl_get_wininstallcontext(void)
+{
+#if defined(_WIN32) && defined (OSSL_WINCTX)
+    return MAKESTR(OSSL_WINCTX);
+#else
+    return "Undefined";
+#endif
+}

+ 4 - 3
libs/openssl/crypto/des/set_key.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -324,8 +324,9 @@ int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
 
 void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
 {
-    static const int shifts2[16] =
-        { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 };
+    static const int shifts2[16] = {
+         0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0
+     };
     register DES_LONG c, d, t, s, t2;
     register const unsigned char *in;
     register DES_LONG *k;

+ 32 - 4
libs/openssl/crypto/dh/dh_check.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -16,6 +16,7 @@
 #include <stdio.h>
 #include "internal/cryptlib.h"
 #include <openssl/bn.h>
+#include <openssl/self_test.h>
 #include "dh_local.h"
 #include "crypto/dh.h"
 
@@ -329,17 +330,27 @@ end:
  * FFC pairwise check from SP800-56A R3.
  *    Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency
  */
-int ossl_dh_check_pairwise(const DH *dh)
+int ossl_dh_check_pairwise(const DH *dh, int return_on_null_numbers)
 {
     int ret = 0;
     BN_CTX *ctx = NULL;
     BIGNUM *pub_key = NULL;
+    OSSL_SELF_TEST *st = NULL;
+    OSSL_CALLBACK *stcb = NULL;
+    void *stcbarg = NULL;
 
     if (dh->params.p == NULL
         || dh->params.g == NULL
         || dh->priv_key == NULL
         || dh->pub_key == NULL)
-        return 0;
+        return return_on_null_numbers;
+
+    OSSL_SELF_TEST_get_callback(dh->libctx, &stcb, &stcbarg);
+    st = OSSL_SELF_TEST_new(stcb, stcbarg);
+    if (st == NULL)
+        goto err;
+    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
+                           OSSL_SELF_TEST_DESC_PCT_DH);
 
     ctx = BN_CTX_new_ex(dh->libctx);
     if (ctx == NULL)
@@ -351,10 +362,27 @@ int ossl_dh_check_pairwise(const DH *dh)
     /* recalculate the public key = (g ^ priv) mod p */
     if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key))
         goto err;
+
+#ifdef FIPS_MODULE
+    {
+        int len;
+        unsigned char bytes[1024] = {0};    /* Max key size of 8192 bits */
+
+        if (BN_num_bytes(pub_key) > (int)sizeof(bytes))
+            goto err;
+        len = BN_bn2bin(pub_key, bytes);
+        OSSL_SELF_TEST_oncorrupt_byte(st, bytes);
+        if (BN_bin2bn(bytes, len, pub_key) == NULL)
+            goto err;
+    }
+#endif
     /* check it matches the existing public_key */
     ret = BN_cmp(pub_key, dh->pub_key) == 0;
-err:
+ err:
     BN_free(pub_key);
     BN_CTX_free(ctx);
+
+    OSSL_SELF_TEST_onend(st, ret);
+    OSSL_SELF_TEST_free(st);
     return ret;
 }

+ 7 - 9
libs/openssl/crypto/dsa/dsa_ameth.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2024 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
@@ -516,26 +516,24 @@ static int dsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
 
 /* NB these are sorted in pkey_id order, lowest first */
 
-const EVP_PKEY_ASN1_METHOD ossl_dsa_asn1_meths[5] = {
-
-    {
-     EVP_PKEY_DSA2,
-     EVP_PKEY_DSA,
-     ASN1_PKEY_ALIAS},
+const EVP_PKEY_ASN1_METHOD ossl_dsa_asn1_meths[4] = {
 
+    /* This aliases NID_dsa with NID_dsa_2 */
     {
      EVP_PKEY_DSA1,
      EVP_PKEY_DSA,
      ASN1_PKEY_ALIAS},
 
+    /* This aliases NID_dsaWithSHA with NID_dsaWithSHA_2 */
     {
      EVP_PKEY_DSA4,
-     EVP_PKEY_DSA,
+     EVP_PKEY_DSA2,
      ASN1_PKEY_ALIAS},
 
+    /* This aliases NID_dsaWithSHA with NID_dsaWithSHA1 */
     {
      EVP_PKEY_DSA3,
-     EVP_PKEY_DSA,
+     EVP_PKEY_DSA2,
      ASN1_PKEY_ALIAS},
 
     {

+ 17 - 7
libs/openssl/crypto/dsa/dsa_pmeth.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2024 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
@@ -78,7 +78,7 @@ static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
                          size_t *siglen, const unsigned char *tbs,
                          size_t tbslen)
 {
-    int ret;
+    int ret, md_size;
     unsigned int sltmp;
     DSA_PKEY_CTX *dctx = ctx->data;
     /*
@@ -88,8 +88,13 @@ static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
      */
     DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey);
 
-    if (dctx->md != NULL && tbslen != (size_t)EVP_MD_get_size(dctx->md))
-        return 0;
+    if (dctx->md != NULL) {
+        md_size = EVP_MD_get_size(dctx->md);
+        if (md_size <= 0)
+            return 0;
+        if (tbslen != (size_t)md_size)
+            return 0;
+    }
 
     ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, dsa);
 
@@ -103,7 +108,7 @@ static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
                            const unsigned char *sig, size_t siglen,
                            const unsigned char *tbs, size_t tbslen)
 {
-    int ret;
+    int ret, md_size;
     DSA_PKEY_CTX *dctx = ctx->data;
     /*
      * Discard const. Its marked as const because this may be a cached copy of
@@ -112,8 +117,13 @@ static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
      */
     DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey);
 
-    if (dctx->md != NULL && tbslen != (size_t)EVP_MD_get_size(dctx->md))
-        return 0;
+    if (dctx->md != NULL) {
+        md_size = EVP_MD_get_size(dctx->md);
+        if (md_size <= 0)
+            return 0;
+        if (tbslen != (size_t)md_size)
+            return 0;
+    }
 
     ret = DSA_verify(0, tbs, tbslen, sig, siglen, dsa);
 

+ 16 - 1
libs/openssl/crypto/ec/curve25519.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2024 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
@@ -5538,6 +5538,21 @@ err:
     return res;
 }
 
+/*
+ * This function should not be necessary since ossl_ed25519_verify() already
+ * does this check internally.
+ * For some reason the FIPS ACVP requires a EDDSA KeyVer test.
+ */
+int
+ossl_ed25519_pubkey_verify(const uint8_t *pub, size_t pub_len)
+{
+    ge_p3 A;
+
+    if (pub_len != ED25519_KEYLEN)
+        return 0;
+    return (ge_frombytes_vartime(&A, pub) == 0);
+}
+
 static const char allzeroes[15];
 
 int

+ 4 - 3
libs/openssl/crypto/ec/curve448/curve448.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright 2015-2016 Cryptography Research, Inc.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -55,8 +55,9 @@ static void gf_invert(gf y, const gf x, int assert_nonzero)
 }
 
 /** identity = (0,1) */
-const curve448_point_t ossl_curve448_point_identity =
-    { {{{{0}}}, {{{1}}}, {{{1}}}, {{{0}}}} };
+const curve448_point_t ossl_curve448_point_identity = {
+    {{{{0}}}, {{{1}}}, {{{1}}}, {{{0}}}}
+};
 
 static void point_double_internal(curve448_point_t p, const curve448_point_t q,
                                   int before_double)

+ 23 - 1
libs/openssl/crypto/ec/curve448/eddsa.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright 2015-2016 Cryptography Research, Inc.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -272,6 +272,17 @@ ossl_c448_ed448_sign_prehash(
                                 context, context_len, propq);
 }
 
+static c448_error_t
+c448_ed448_pubkey_verify(const uint8_t *pub, size_t pub_len)
+{
+    curve448_point_t pk_point;
+
+    if (pub_len != EDDSA_448_PUBLIC_BYTES)
+        return C448_FAILURE;
+
+    return ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pub);
+}
+
 c448_error_t
 ossl_c448_ed448_verify(
                     OSSL_LIB_CTX *ctx,
@@ -380,6 +391,17 @@ ossl_ed448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig,
                                 propq) == C448_SUCCESS;
 }
 
+/*
+ * This function should not be necessary since ossl_ed448_verify() already
+ * does this check internally.
+ * For some reason the FIPS ACVP requires a EDDSA KeyVer test.
+ */
+int
+ossl_ed448_pubkey_verify(const uint8_t *pub, size_t pub_len)
+{
+    return c448_ed448_pubkey_verify(pub, pub_len);
+}
+
 int
 ossl_ed448_verify(OSSL_LIB_CTX *ctx,
                   const uint8_t *message, size_t message_len,

+ 2 - 3
libs/openssl/crypto/ec/ec_backend.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2024 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
@@ -184,8 +184,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl,
     param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P);
     param_a = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A);
     param_b = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B);
-    if (tmpl != NULL || param_p != NULL || param_a != NULL || param_b != NULL)
-    {
+    if (tmpl != NULL || param_p != NULL || param_a != NULL || param_b != NULL) {
         BIGNUM *p = BN_CTX_get(bnctx);
         BIGNUM *a = BN_CTX_get(bnctx);
         BIGNUM *b = BN_CTX_get(bnctx);

+ 31 - 7
libs/openssl/crypto/ec/ec_curve.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -383,7 +383,7 @@ static const struct {
 
 static const struct {
     EC_CURVE_DATA h;
-    unsigned char data[20 + 32 * 6];
+    unsigned char data[20 + 32 * 8];
 } _EC_X9_62_PRIME_256V1 = {
     {
         NID_X9_62_prime_field, 20, 32, 1
@@ -415,7 +415,15 @@ static const struct {
         /* order */
         0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
         0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
-        0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
+        0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51,
+        /* RR for prime */
+        0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+        /* RR for order */
+        0x66, 0xe1, 0x2d, 0x94, 0xf3, 0xd9, 0x56, 0x20, 0x28, 0x45, 0xb2, 0x39,
+        0x2b, 0x6b, 0xec, 0x59, 0x46, 0x99, 0x79, 0x9c, 0x49, 0xbd, 0x6f, 0xa6,
+        0x83, 0x24, 0x4c, 0x95, 0xbe, 0x79, 0xee, 0xa2
     }
 };
 
@@ -3168,6 +3176,24 @@ static EC_GROUP *ec_group_new_from_data(OSSL_LIB_CTX *libctx,
     seed_len = data->seed_len;
     param_len = data->param_len;
     params = (const unsigned char *)(data + 1); /* skip header */
+
+    if (curve.meth != NULL) {
+        meth = curve.meth();
+        if ((group = ossl_ec_group_new_ex(libctx, propq, meth)) == NULL) {
+            ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
+            goto err;
+        }
+        if (group->meth->group_full_init != NULL) {
+            if (!group->meth->group_full_init(group, params)){
+                ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
+                goto err;
+            }
+            EC_GROUP_set_curve_name(group, curve.nid);
+            BN_CTX_free(ctx);
+            return group;
+        }
+    }
+
     params += seed_len;         /* skip seed */
 
     if ((p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) == NULL
@@ -3177,10 +3203,8 @@ static EC_GROUP *ec_group_new_from_data(OSSL_LIB_CTX *libctx,
         goto err;
     }
 
-    if (curve.meth != 0) {
-        meth = curve.meth();
-        if (((group = ossl_ec_group_new_ex(libctx, propq, meth)) == NULL) ||
-            (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
+    if (group != NULL) {
+        if (group->meth->group_set_curve(group, p, a, b, ctx) == 0) {
             ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
             goto err;
         }

+ 6 - 0
libs/openssl/crypto/ec/ec_key.c

@@ -563,10 +563,16 @@ int ossl_ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx)
     int ret = 0;
     EC_POINT *point = NULL;
     const BIGNUM *order = NULL;
+    const BIGNUM *cofactor = EC_GROUP_get0_cofactor(eckey->group);
 
     if (!ossl_ec_key_public_check_quick(eckey, ctx))
         return 0;
 
+    if (cofactor != NULL && BN_is_one(cofactor)) {
+        /* Skip the unnecessary expensive computation for curves with cofactor of 1. */
+        return 1;
+    }
+
     point = EC_POINT_new(eckey->group);
     if (point == NULL)
         return 0;

+ 4 - 0
libs/openssl/crypto/ec/ec_lib.c

@@ -747,9 +747,13 @@ void EC_POINT_free(EC_POINT *point)
     if (point == NULL)
         return;
 
+#ifdef OPENSSL_PEDANTIC_ZEROIZATION
+    EC_POINT_clear_free(point);
+#else
     if (point->meth->point_finish != 0)
         point->meth->point_finish(point);
     OPENSSL_free(point);
+#endif
 }
 
 void EC_POINT_clear_free(EC_POINT *point)

+ 2 - 1
libs/openssl/crypto/ec/ec_local.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -196,6 +196,7 @@ struct ec_method_st {
     int (*ladder_post)(const EC_GROUP *group,
                        EC_POINT *r, EC_POINT *s,
                        EC_POINT *p, BN_CTX *ctx);
+    int (*group_full_init)(EC_GROUP *group, const unsigned char *data);
 };
 
 /*

+ 10 - 16
libs/openssl/crypto/ec/ec_print.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2024 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
@@ -9,18 +9,17 @@
 
 #include <string.h> /* strlen */
 #include <openssl/crypto.h>
+#include "internal/cryptlib.h"
 #include "ec_local.h"
 
-static const char *HEX_DIGITS = "0123456789ABCDEF";
-
 /* the return value must be freed (using OPENSSL_free()) */
 char *EC_POINT_point2hex(const EC_GROUP *group,
                          const EC_POINT *point,
                          point_conversion_form_t form, BN_CTX *ctx)
 {
     char *ret, *p;
-    size_t buf_len = 0, i;
-    unsigned char *buf = NULL, *pbuf;
+    size_t buf_len, i;
+    unsigned char *buf = NULL;
 
     buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
 
@@ -28,21 +27,16 @@ char *EC_POINT_point2hex(const EC_GROUP *group,
         return NULL;
 
     ret = OPENSSL_malloc(buf_len * 2 + 2);
-    if (ret == NULL) {
-        OPENSSL_free(buf);
-        return NULL;
-    }
+    if (ret == NULL)
+        goto err;
+
     p = ret;
-    pbuf = buf;
-    for (i = buf_len; i > 0; i--) {
-        int v = (int)*(pbuf++);
-        *(p++) = HEX_DIGITS[v >> 4];
-        *(p++) = HEX_DIGITS[v & 0x0F];
-    }
+    for (i = 0; i < buf_len; ++i)
+        p += ossl_to_hex(p, buf[i]);
     *p = '\0';
 
+ err:
     OPENSSL_free(buf);
-
     return ret;
 }
 

+ 2 - 2
libs/openssl/crypto/ec/ecp_mont.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -258,7 +258,7 @@ int ossl_ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a
 
     ret = 1;
 
-  err:
+ err:
     BN_CTX_end(ctx);
     BN_CTX_free(new_ctx);
     return ret;

+ 3 - 0
libs/openssl/crypto/ec/ecx_key.c

@@ -75,6 +75,9 @@ void ossl_ecx_key_free(ECX_KEY *key)
     REF_ASSERT_ISNT(i < 0);
 
     OPENSSL_free(key->propq);
+#ifdef OPENSSL_PEDANTIC_ZEROIZATION
+    OPENSSL_cleanse(&key->pubkey, sizeof(key->pubkey));
+#endif
     OPENSSL_secure_clear_free(key->privkey, key->keylen);
     CRYPTO_FREE_REF(&key->references);
     OPENSSL_free(key);

+ 108 - 6
libs/openssl/crypto/encode_decode/decoder_lib.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2025 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
@@ -210,6 +210,34 @@ int OSSL_DECODER_CTX_set_input_structure(OSSL_DECODER_CTX *ctx,
     return 1;
 }
 
+OSSL_DECODER_INSTANCE *
+ossl_decoder_instance_new_forprov(OSSL_DECODER *decoder, void *provctx,
+                                  const char *input_structure)
+{
+    void *decoderctx;
+
+    if (!ossl_assert(decoder != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    decoderctx = decoder->newctx(provctx);
+    if (decoderctx == NULL)
+        return 0;
+    if (input_structure != NULL && decoder->set_ctx_params != NULL) {
+        OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+        params[0] =
+            OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
+                                             (char *)input_structure, 0);
+        if (!decoder->set_ctx_params(decoderctx, params)) {
+            decoder->freectx(decoderctx);
+            return 0;
+        }
+    }
+    return ossl_decoder_instance_new(decoder, decoderctx);
+}
+
 OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder,
                                                  void *decoderctx)
 {
@@ -312,6 +340,16 @@ OSSL_DECODER_INSTANCE *ossl_decoder_instance_dup(const OSSL_DECODER_INSTANCE *sr
     return NULL;
 }
 
+void ossl_decoder_ctx_set_harderr(OSSL_DECODER_CTX *ctx)
+{
+    ctx->harderr = 1;
+}
+
+int ossl_decoder_ctx_get_harderr(const OSSL_DECODER_CTX *ctx)
+{
+    return ctx->harderr;
+}
+
 int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx,
                                       OSSL_DECODER_INSTANCE *di)
 {
@@ -438,6 +476,20 @@ static void collect_extra_decoder(OSSL_DECODER *decoder, void *arg)
         if ((decoderctx = decoder->newctx(provctx)) == NULL)
             return;
 
+        if (decoder->set_ctx_params != NULL
+            && data->ctx->input_structure != NULL) {
+            OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+            const char *str = data->ctx->input_structure;
+
+            params[0] =
+                OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
+                                                 (char *)str, 0);
+            if (!decoder->set_ctx_params(decoderctx, params)) {
+                decoder->freectx(decoderctx);
+                return;
+            }
+        }
+
         if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) {
             decoder->freectx(decoderctx);
             return;
@@ -485,6 +537,14 @@ static void collect_extra_decoder(OSSL_DECODER *decoder, void *arg)
     }
 }
 
+static int decoder_sk_cmp(const OSSL_DECODER_INSTANCE *const *a,
+                          const OSSL_DECODER_INSTANCE *const *b)
+{
+    if ((*a)->score == (*b)->score)
+        return (*a)->order - (*b)->order;
+    return (*a)->score - (*b)->score;
+}
+
 int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
                                OSSL_LIB_CTX *libctx, const char *propq)
 {
@@ -543,6 +603,26 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
     OSSL_DECODER_do_all_provided(libctx, collect_all_decoders, skdecoders);
     numdecoders = sk_OSSL_DECODER_num(skdecoders);
 
+    /*
+     * If there are provided or default properties, sort the initial decoder list
+     * by property matching score so that the highest scored provider is selected
+     * first.
+     */
+    if (propq != NULL || ossl_ctx_global_properties(libctx, 0) != NULL) {
+        int num_decoder_insts = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
+        int i;
+        OSSL_DECODER_INSTANCE *di;
+        sk_OSSL_DECODER_INSTANCE_compfunc old_cmp =
+            sk_OSSL_DECODER_INSTANCE_set_cmp_func(ctx->decoder_insts, decoder_sk_cmp);
+
+        for (i = 0; i < num_decoder_insts; i++) {
+            di = sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
+            di->order = i;
+        }
+        sk_OSSL_DECODER_INSTANCE_sort(ctx->decoder_insts);
+        sk_OSSL_DECODER_INSTANCE_set_cmp_func(ctx->decoder_insts, old_cmp);
+    }
+
     memset(&data, 0, sizeof(data));
     data.ctx = ctx;
     data.w_prev_start = 0;
@@ -723,6 +803,8 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
     struct decoder_process_data_st new_data;
     const char *data_type = NULL;
     const char *data_structure = NULL;
+    /* Saved to restore on return, mutated in PEM->DER transition. */
+    const char *start_input_type = ctx->start_input_type;
 
     /*
      * This is an indicator up the call stack that something was indeed
@@ -813,6 +895,23 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
         if (p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &data_structure))
             goto end;
 
+        /* Get the new input type if there is one */
+        p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_INPUT_TYPE);
+        if (p != NULL) {
+            if (!OSSL_PARAM_get_utf8_string_ptr(p, &ctx->start_input_type))
+                goto end;
+            /*
+             * When switching PKCS8 from PEM to DER we decrypt the data if needed
+             * and then determine the algorithm OID.  Likewise, with SPKI, only
+             * this time sans decryption.
+             */
+            if (ctx->input_structure != NULL
+                && (OPENSSL_strcasecmp(ctx->input_structure, "SubjectPublicKeyInfo") == 0
+                    || OPENSSL_strcasecmp(data_structure, "PrivateKeyInfo") == 0
+                    || OPENSSL_strcasecmp(ctx->input_structure, "PrivateKeyInfo") == 0))
+                data->flag_input_structure_checked = 1;
+        }
+
         /*
          * If the data structure is "type-specific" and the data type is
          * given, we drop the data structure.  The reasoning is that the
@@ -863,6 +962,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
             sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
         OSSL_DECODER *new_decoder =
             OSSL_DECODER_INSTANCE_get_decoder(new_decoder_inst);
+        const char *new_decoder_name = NULL;
         void *new_decoderctx =
             OSSL_DECODER_INSTANCE_get_decoder_ctx(new_decoder_inst);
         const char *new_input_type =
@@ -873,12 +973,13 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
                                                       &n_i_s_was_set);
 
         OSSL_TRACE_BEGIN(DECODER) {
+            new_decoder_name = OSSL_DECODER_get0_name(new_decoder);
             BIO_printf(trc_out,
                        "(ctx %p) %s [%u] Considering decoder instance %p (decoder %p):\n"
                        "    %s with %s\n",
                        (void *)new_data.ctx, LEVEL, (unsigned int)i,
                        (void *)new_decoder_inst, (void *)new_decoder,
-                       OSSL_DECODER_get0_name(new_decoder),
+                       new_decoder_name,
                        OSSL_DECODER_get0_properties(new_decoder));
         } OSSL_TRACE_END(DECODER);
 
@@ -983,9 +1084,9 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
         /* Recurse */
         OSSL_TRACE_BEGIN(DECODER) {
             BIO_printf(trc_out,
-                       "(ctx %p) %s [%u] Running decoder instance %p\n",
+                       "(ctx %p) %s [%u] Running decoder instance %s (%p)\n",
                        (void *)new_data.ctx, LEVEL, (unsigned int)i,
-                       (void *)new_decoder_inst);
+                       new_decoder_name, (void *)new_decoder_inst);
         } OSSL_TRACE_END(DECODER);
 
         /*
@@ -1005,10 +1106,10 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
 
         OSSL_TRACE_BEGIN(DECODER) {
             BIO_printf(trc_out,
-                       "(ctx %p) %s [%u] Running decoder instance %p => %d"
+                       "(ctx %p) %s [%u] Running decoder instance %s (%p) => %d"
                        " (recursed further: %s, construct called: %s)\n",
                        (void *)new_data.ctx, LEVEL, (unsigned int)i,
-                       (void *)new_decoder_inst, ok,
+                       new_decoder_name, (void *)new_decoder_inst, ok,
                        new_data.flag_next_level_called ? "yes" : "no",
                        new_data.flag_construct_called ? "yes" : "no");
         } OSSL_TRACE_END(DECODER);
@@ -1033,5 +1134,6 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
  end:
     ossl_core_bio_free(cbio);
     BIO_free(new_data.bio);
+    ctx->start_input_type = start_input_type;
     return ok;
 }

+ 13 - 3
libs/openssl/crypto/encode_decode/decoder_meth.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2025 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
@@ -24,6 +24,16 @@
  */
 #define NAME_SEPARATOR ':'
 
+static void ossl_decoder_free(void *data)
+{
+    OSSL_DECODER_free(data);
+}
+
+static int ossl_decoder_up_ref(void *data)
+{
+    return OSSL_DECODER_up_ref(data);
+}
+
 /* Simple method structure constructor and destructor */
 static OSSL_DECODER *ossl_decoder_new(void)
 {
@@ -191,8 +201,8 @@ static int put_decoder_in_store(void *store, void *method,
         return 0;
 
     return ossl_method_store_add(store, prov, id, propdef, method,
-                                 (int (*)(void *))OSSL_DECODER_up_ref,
-                                 (void (*)(void *))OSSL_DECODER_free);
+                                 ossl_decoder_up_ref,
+                                 ossl_decoder_free);
 }
 
 /* Create and populate a decoder method */

+ 94 - 19
libs/openssl/crypto/encode_decode/decoder_pkey.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2025 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
@@ -65,6 +65,7 @@ struct decoder_pkey_data_st {
     STACK_OF(EVP_KEYMGMT) *keymgmts;
     char *object_type;           /* recorded object data type, may be NULL */
     void **object;               /* Where the result should end up */
+    OSSL_DECODER_CTX *ctx;       /* The parent decoder context */
 };
 
 static int decoder_construct_pkey(OSSL_DECODER_INSTANCE *decoder_inst,
@@ -171,6 +172,14 @@ static int decoder_construct_pkey(OSSL_DECODER_INSTANCE *decoder_inst,
             keydata = import_data.keydata;
             import_data.keydata = NULL;
         }
+        /*
+         * When load or import fails, because this is not an acceptable key
+         * (despite the provided key material being syntactically valid), the
+         * reason why the key is rejected would be lost, unless we signal a
+         * hard error, and suppress resetting for another try.
+         */
+        if (keydata == NULL)
+            ossl_decoder_ctx_set_harderr(data->ctx);
 
         if (keydata != NULL
             && (pkey = evp_keymgmt_util_make_pkey(keymgmt, keydata)) == NULL)
@@ -213,15 +222,21 @@ struct collect_data_st {
     int total;      /* number of matching results */
     char error_occurred;
     char keytype_resolved;
+    OSSL_PROPERTY_LIST *pq;
 
     STACK_OF(EVP_KEYMGMT) *keymgmts;
 };
 
-static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
-                                    void *provctx, struct collect_data_st *data)
+/*
+ * Add decoder instance to the decoder context if it is compatible. Returns 1
+ * if a decoder was added, 0 otherwise.
+ */
+static int collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
+                                   void *provctx, struct collect_data_st *data)
 {
     void *decoderctx = NULL;
     OSSL_DECODER_INSTANCE *di = NULL;
+    const OSSL_PROPERTY_LIST *props;
 
     /*
      * We already checked the EVP_KEYMGMT is applicable in check_keymgmt so we
@@ -230,17 +245,31 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
 
     if (keymgmt->name_id != decoder->base.id)
         /* Mismatch is not an error, continue. */
-        return;
+        return 0;
 
     if ((decoderctx = decoder->newctx(provctx)) == NULL) {
         data->error_occurred = 1;
-        return;
+        return 0;
     }
 
     if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) {
         decoder->freectx(decoderctx);
         data->error_occurred = 1;
-        return;
+        return 0;
+    }
+
+    /*
+     * Input types must be compatible, but we must accept DER encoders when the
+     * start input type is "PEM".
+     */
+    if (data->ctx->start_input_type != NULL
+        && di->input_type != NULL
+        && OPENSSL_strcasecmp(di->input_type, data->ctx->start_input_type) != 0
+        && (OPENSSL_strcasecmp(di->input_type, "DER") != 0
+            || OPENSSL_strcasecmp(data->ctx->start_input_type, "PEM") != 0)) {
+        /* Mismatch is not an error, continue. */
+        ossl_decoder_instance_free(di);
+        return 0;
     }
 
     OSSL_TRACE_BEGIN(DECODER) {
@@ -252,13 +281,30 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
                    OSSL_DECODER_get0_properties(decoder));
     } OSSL_TRACE_END(DECODER);
 
+    /*
+     * Get the property match score so the decoders can be prioritized later.
+     */
+    props = ossl_decoder_parsed_properties(decoder);
+    if (data->pq != NULL && props != NULL) {
+        di->score = ossl_property_match_count(data->pq, props);
+        /*
+         * Mismatch of mandatory properties is not an error, the decoder is just
+         * ignored, continue.
+         */
+        if (di->score < 0) {
+            ossl_decoder_instance_free(di);
+            return 0;
+        }
+    }
+
     if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) {
         ossl_decoder_instance_free(di);
         data->error_occurred = 1;
-        return;
+        return 0;
     }
 
     ++data->total;
+    return 1;
 }
 
 static void collect_decoder(OSSL_DECODER *decoder, void *arg)
@@ -298,7 +344,9 @@ static void collect_decoder(OSSL_DECODER *decoder, void *arg)
     for (i = 0; i < end_i; ++i) {
         keymgmt = sk_EVP_KEYMGMT_value(keymgmts, i);
 
-        collect_decoder_keymgmt(keymgmt, decoder, provctx, data);
+        /* Only add this decoder once */
+        if (collect_decoder_keymgmt(keymgmt, decoder, provctx, data))
+            break;
         if (data->error_occurred)
             return;
     }
@@ -384,6 +432,8 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
     struct decoder_pkey_data_st *process_data = NULL;
     struct collect_data_st collect_data = { NULL };
     STACK_OF(EVP_KEYMGMT) *keymgmts = NULL;
+    OSSL_PROPERTY_LIST **plp;
+    OSSL_PROPERTY_LIST *pq = NULL, *p2 = NULL;
 
     OSSL_TRACE_BEGIN(DECODER) {
         const char *input_type = ctx->start_input_type;
@@ -419,6 +469,25 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
     process_data->selection = ctx->selection;
     process_data->keymgmts  = keymgmts;
 
+    /*
+     * Collect passed and default properties to prioritize the decoders.
+     */
+    if (propquery != NULL)
+        p2 = pq = ossl_parse_query(libctx, propquery, 1);
+
+    plp = ossl_ctx_global_properties(libctx, 0);
+    if (plp != NULL && *plp != NULL) {
+        if (pq == NULL) {
+            pq = *plp;
+        } else {
+            p2 = ossl_property_merge(pq, *plp);
+            ossl_property_free(pq);
+            if (p2 == NULL)
+                goto err;
+            pq = p2;
+        }
+    }
+
     /*
      * Enumerate all keymgmts into a stack.
      *
@@ -434,10 +503,11 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
      * upfront, as this ensures that the names for all loaded providers have
      * been registered by the time we try to resolve the keytype string.
      */
-    collect_data.ctx        = ctx;
-    collect_data.libctx     = libctx;
-    collect_data.keymgmts   = keymgmts;
-    collect_data.keytype    = keytype;
+    collect_data.ctx            = ctx;
+    collect_data.libctx         = libctx;
+    collect_data.keymgmts       = keymgmts;
+    collect_data.keytype        = keytype;
+    collect_data.pq             = pq;
     EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, &collect_data);
 
     if (collect_data.error_occurred)
@@ -473,6 +543,7 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
     ok = 1;
  err:
     decoder_clean_pkey_construct_arg(process_data);
+    ossl_property_free(p2);
     return ok;
 }
 
@@ -561,6 +632,7 @@ ossl_decoder_ctx_for_pkey_dup(OSSL_DECODER_CTX *src,
         process_data_dest->object    = (void **)pkey;
         process_data_dest->libctx    = process_data_src->libctx;
         process_data_dest->selection = process_data_src->selection;
+        process_data_dest->ctx       = dest;
         if (!OSSL_DECODER_CTX_set_construct_data(dest, process_data_dest)) {
             ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
             goto err;
@@ -576,11 +648,7 @@ ossl_decoder_ctx_for_pkey_dup(OSSL_DECODER_CTX *src,
 
     return dest;
  err:
-    if (process_data_dest != NULL) {
-        OPENSSL_free(process_data_dest->propq);
-        sk_EVP_KEYMGMT_pop_free(process_data_dest->keymgmts, EVP_KEYMGMT_free);
-        OPENSSL_free(process_data_dest);
-    }
+    decoder_clean_pkey_construct_arg(process_data_dest);
     OSSL_DECODER_CTX_free(dest);
     return NULL;
 }
@@ -746,20 +814,27 @@ OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY **pkey,
 {
     OSSL_DECODER_CTX *ctx = NULL;
     OSSL_PARAM decoder_params[] = {
+        OSSL_PARAM_END,
         OSSL_PARAM_END,
         OSSL_PARAM_END
     };
     DECODER_CACHE *cache
         = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_CACHE_INDEX);
     DECODER_CACHE_ENTRY cacheent, *res, *newcache = NULL;
+    int i = 0;
 
     if (cache == NULL) {
         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB);
         return NULL;
     }
+    if (input_structure != NULL)
+        decoder_params[i++] =
+            OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
+                                             (char *)input_structure, 0);
     if (propquery != NULL)
-        decoder_params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DECODER_PARAM_PROPERTIES,
-                                                             (char *)propquery, 0);
+        decoder_params[i++] =
+            OSSL_PARAM_construct_utf8_string(OSSL_DECODER_PARAM_PROPERTIES,
+                                             (char *)propquery, 0);
 
     /* It is safe to cast away the const here */
     cacheent.input_type = (char *)input_type;

+ 182 - 1
libs/openssl/crypto/encode_decode/encoder_lib.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -7,6 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
+#include <ctype.h>
+
 #include <openssl/core_names.h>
 #include <openssl/bio.h>
 #include <openssl/encoder.h>
@@ -14,10 +16,31 @@
 #include <openssl/params.h>
 #include <openssl/provider.h>
 #include <openssl/trace.h>
+#include <crypto/bn.h>
 #include "internal/bio.h"
+#include "internal/ffc.h"
 #include "internal/provider.h"
+#include "internal/encoder.h"
 #include "encoder_local.h"
 
+/* Number of octets per line */
+#define LABELED_BUF_PRINT_WIDTH    15
+
+# ifdef SIXTY_FOUR_BIT_LONG
+#  define BN_FMTu "%lu"
+#  define BN_FMTx "%lx"
+# endif
+
+# ifdef SIXTY_FOUR_BIT
+#  define BN_FMTu "%llu"
+#  define BN_FMTx "%llx"
+# endif
+
+# ifdef THIRTY_TWO_BIT
+#  define BN_FMTu "%u"
+#  define BN_FMTx "%x"
+# endif
+
 struct encoder_process_data_st {
     OSSL_ENCODER_CTX *ctx;
 
@@ -675,3 +698,161 @@ static int encoder_process(struct encoder_process_data_st *data)
         data->ctx->cleanup(data->ctx->construct_data);
     return ok;
 }
+
+int ossl_bio_print_labeled_bignum(BIO *out, const char *label, const BIGNUM *bn)
+{
+    int ret = 0, use_sep = 0;
+    char *hex_str = NULL, *p;
+    const char spaces[] = "    ";
+    const char *post_label_spc = " ";
+
+    const char *neg = "";
+    int bytes;
+
+    if (bn == NULL)
+        return 0;
+    if (label == NULL) {
+        label = "";
+        post_label_spc = "";
+    }
+
+    if (BN_is_zero(bn))
+        return BIO_printf(out, "%s%s0\n", label, post_label_spc);
+
+    if (BN_num_bytes(bn) <= BN_BYTES) {
+        BN_ULONG *words = bn_get_words(bn);
+
+        if (BN_is_negative(bn))
+            neg = "-";
+
+        return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n",
+                          label, post_label_spc, neg, words[0], neg, words[0]);
+    }
+
+    hex_str = BN_bn2hex(bn);
+    if (hex_str == NULL)
+        return 0;
+
+    p = hex_str;
+    if (*p == '-') {
+        ++p;
+        neg = " (Negative)";
+    }
+    if (BIO_printf(out, "%s%s\n", label, neg) <= 0)
+        goto err;
+
+    /* Keep track of how many bytes we have printed out so far */
+    bytes = 0;
+
+    if (BIO_printf(out, "%s", spaces) <= 0)
+        goto err;
+
+    /* Add a leading 00 if the top bit is set */
+    if (*p >= '8') {
+        if (BIO_printf(out, "%02x", 0) <= 0)
+            goto err;
+        ++bytes;
+        use_sep = 1;
+    }
+    while (*p != '\0') {
+        /* Do a newline after every 15 hex bytes + add the space indent */
+        if ((bytes % 15) == 0 && bytes > 0) {
+            if (BIO_printf(out, ":\n%s", spaces) <= 0)
+                goto err;
+            use_sep = 0; /* The first byte on the next line doesn't have a : */
+        }
+        if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "",
+                       tolower((unsigned char)p[0]),
+                       tolower((unsigned char)p[1])) <= 0)
+            goto err;
+        ++bytes;
+        p += 2;
+        use_sep = 1;
+    }
+    if (BIO_printf(out, "\n") <= 0)
+        goto err;
+    ret = 1;
+err:
+    OPENSSL_free(hex_str);
+    return ret;
+}
+
+int ossl_bio_print_labeled_buf(BIO *out, const char *label,
+                           const unsigned char *buf, size_t buflen)
+{
+    size_t i;
+
+    if (BIO_printf(out, "%s\n", label) <= 0)
+        return 0;
+
+    for (i = 0; i < buflen; i++) {
+        if ((i % LABELED_BUF_PRINT_WIDTH) == 0) {
+            if (i > 0 && BIO_printf(out, "\n") <= 0)
+                return 0;
+            if (BIO_printf(out, "    ") <= 0)
+                return 0;
+        }
+
+        if (BIO_printf(out, "%02x%s", buf[i],
+                                 (i == buflen - 1) ? "" : ":") <= 0)
+            return 0;
+    }
+    if (BIO_printf(out, "\n") <= 0)
+        return 0;
+
+    return 1;
+}
+
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA)
+int ossl_bio_print_ffc_params(BIO *out, const FFC_PARAMS *ffc)
+{
+    if (ffc->nid != NID_undef) {
+#ifndef OPENSSL_NO_DH
+        const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid);
+        const char *name = ossl_ffc_named_group_get_name(group);
+
+        if (name == NULL)
+            goto err;
+        if (BIO_printf(out, "GROUP: %s\n", name) <= 0)
+            goto err;
+        return 1;
+#else
+        /* How could this be? We should not have a nid in a no-dh build. */
+        goto err;
+#endif
+    }
+
+    if (!ossl_bio_print_labeled_bignum(out, "P:   ", ffc->p))
+        goto err;
+    if (ffc->q != NULL) {
+        if (!ossl_bio_print_labeled_bignum(out, "Q:   ", ffc->q))
+            goto err;
+    }
+    if (!ossl_bio_print_labeled_bignum(out, "G:   ", ffc->g))
+        goto err;
+    if (ffc->j != NULL) {
+        if (!ossl_bio_print_labeled_bignum(out, "J:   ", ffc->j))
+            goto err;
+    }
+    if (ffc->seed != NULL) {
+        if (!ossl_bio_print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen))
+            goto err;
+    }
+    if (ffc->gindex != -1) {
+        if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0)
+            goto err;
+    }
+    if (ffc->pcounter != -1) {
+        if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0)
+            goto err;
+    }
+    if (ffc->h != 0) {
+        if (BIO_printf(out, "h: %d\n", ffc->h) <= 0)
+            goto err;
+    }
+    return 1;
+err:
+    return 0;
+}
+
+#endif

+ 7 - 1
libs/openssl/crypto/encode_decode/encoder_local.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -12,6 +12,7 @@
 #include <openssl/safestack.h>
 #include <openssl/encoder.h>
 #include <openssl/decoder.h>
+#include "crypto/decoder.h"
 #include "internal/cryptlib.h"
 #include "internal/passphrase.h"
 #include "internal/property.h"
@@ -108,6 +109,8 @@ struct ossl_decoder_instance_st {
     const char *input_type;      /* Never NULL */
     const char *input_structure; /* May be NULL */
     int input_type_id;
+    int order;                   /* For stable ordering of decoders wrt proqs */
+    int score;                   /* For ordering decoders wrt proqs */
 
     unsigned int flag_input_structure_was_set : 1;
 };
@@ -156,6 +159,9 @@ struct ossl_decoder_ctx_st {
 
     /* For any function that needs a passphrase reader */
     struct ossl_passphrase_data_st pwdata;
+
+    /* Signal that further processing should not continue. */
+    int harderr;
 };
 
 const OSSL_PROPERTY_LIST *

+ 13 - 3
libs/openssl/crypto/encode_decode/encoder_meth.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -24,6 +24,16 @@
  */
 #define NAME_SEPARATOR ':'
 
+static void ossl_encoder_free(void *data)
+{
+    OSSL_ENCODER_free(data);
+}
+
+static int ossl_encoder_up_ref(void *data)
+{
+    return OSSL_ENCODER_up_ref(data);
+}
+
 /* Simple method structure constructor and destructor */
 static OSSL_ENCODER *ossl_encoder_new(void)
 {
@@ -191,8 +201,8 @@ static int put_encoder_in_store(void *store, void *method,
         return 0;
 
     return ossl_method_store_add(store, prov, id, propdef, method,
-                                 (int (*)(void *))OSSL_ENCODER_up_ref,
-                                 (void (*)(void *))OSSL_ENCODER_free);
+                                 ossl_encoder_up_ref,
+                                 ossl_encoder_free);
 }
 
 /* Create and populate a encoder method */

+ 47 - 15
libs/openssl/crypto/evp/asymcipher.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2025 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
@@ -17,12 +17,23 @@
 #include "crypto/evp.h"
 #include "evp_local.h"
 
+static void evp_asym_cipher_free(void *data)
+{
+    EVP_ASYM_CIPHER_free(data);
+}
+
+static int evp_asym_cipher_up_ref(void *data)
+{
+    return EVP_ASYM_CIPHER_up_ref(data);
+}
+
 static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
                                      const OSSL_PARAM params[])
 {
     int ret = 0;
     void *provkey = NULL;
     EVP_ASYM_CIPHER *cipher = NULL;
+    const char *desc;
     EVP_KEYMGMT *tmp_keymgmt = NULL;
     const OSSL_PROVIDER *tmp_prov = NULL;
     const char *supported_ciph = NULL;
@@ -149,10 +160,12 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
         goto err;
     }
 
+    desc = cipher->description != NULL ? cipher->description : "";
     switch (operation) {
     case EVP_PKEY_OP_ENCRYPT:
         if (cipher->encrypt_init == NULL) {
-            ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+            ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED,
+                           "%s encrypt_init:%s", cipher->type_name, desc);
             ret = -2;
             goto err;
         }
@@ -160,7 +173,8 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
         break;
     case EVP_PKEY_OP_DECRYPT:
         if (cipher->decrypt_init == NULL) {
-            ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+            ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED,
+                           "%s decrypt_init:%s", cipher->type_name, desc);
             ret = -2;
             goto err;
         }
@@ -228,6 +242,8 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
                      unsigned char *out, size_t *outlen,
                      const unsigned char *in, size_t inlen)
 {
+    EVP_ASYM_CIPHER *cipher;
+    const char *desc;
     int ret;
 
     if (ctx == NULL) {
@@ -243,8 +259,14 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
     if (ctx->op.ciph.algctx == NULL)
         goto legacy;
 
-    ret = ctx->op.ciph.cipher->encrypt(ctx->op.ciph.algctx, out, outlen,
-                                       (out == NULL ? 0 : *outlen), in, inlen);
+    cipher = ctx->op.ciph.cipher;
+    desc = cipher->description != NULL ? cipher->description : "";
+    ERR_set_mark();
+    ret = cipher->encrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
+    if (ret <= 0 && ERR_count_to_mark() == 0)
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
+                       "%s encrypt:%s", cipher->type_name, desc);
+    ERR_clear_last_mark();
     return ret;
 
  legacy:
@@ -270,6 +292,8 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
                      unsigned char *out, size_t *outlen,
                      const unsigned char *in, size_t inlen)
 {
+    EVP_ASYM_CIPHER *cipher;
+    const char *desc;
     int ret;
 
     if (ctx == NULL) {
@@ -285,8 +309,15 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
     if (ctx->op.ciph.algctx == NULL)
         goto legacy;
 
-    ret = ctx->op.ciph.cipher->decrypt(ctx->op.ciph.algctx, out, outlen,
-                                       (out == NULL ? 0 : *outlen), in, inlen);
+    cipher = ctx->op.ciph.cipher;
+    desc = cipher->description != NULL ? cipher->description : "";
+    ERR_set_mark();
+    ret = cipher->decrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
+    if (ret <= 0 && ERR_count_to_mark() == 0)
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
+                       "%s decrypt:%s", cipher->type_name, desc);
+    ERR_clear_last_mark();
+
     return ret;
 
  legacy:
@@ -324,12 +355,13 @@ static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov)
     if (cipher == NULL)
         return NULL;
 
-    if (!CRYPTO_NEW_REF(&cipher->refcnt, 1)) {
+    if (!CRYPTO_NEW_REF(&cipher->refcnt, 1)
+            || !ossl_provider_up_ref(prov)) {
+        CRYPTO_FREE_REF(&cipher->refcnt);
         OPENSSL_free(cipher);
         return NULL;
     }
     cipher->prov = prov;
-    ossl_provider_up_ref(prov);
 
     return cipher;
 }
@@ -484,8 +516,8 @@ EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
 {
     return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties,
                              evp_asym_cipher_from_algorithm,
-                             (int (*)(void *))EVP_ASYM_CIPHER_up_ref,
-                             (void (*)(void *))EVP_ASYM_CIPHER_free);
+                             evp_asym_cipher_up_ref,
+                             evp_asym_cipher_free);
 }
 
 EVP_ASYM_CIPHER *evp_asym_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
@@ -495,8 +527,8 @@ EVP_ASYM_CIPHER *evp_asym_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
     return evp_generic_fetch_from_prov(prov, OSSL_OP_ASYM_CIPHER,
                                        algorithm, properties,
                                        evp_asym_cipher_from_algorithm,
-                                       (int (*)(void *))EVP_ASYM_CIPHER_up_ref,
-                                       (void (*)(void *))EVP_ASYM_CIPHER_free);
+                                       evp_asym_cipher_up_ref,
+                                       evp_asym_cipher_free);
 }
 
 int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name)
@@ -527,8 +559,8 @@ void EVP_ASYM_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx,
     evp_generic_do_all(libctx, OSSL_OP_ASYM_CIPHER,
                        (void (*)(void *, void *))fn, arg,
                        evp_asym_cipher_from_algorithm,
-                       (int (*)(void *))EVP_ASYM_CIPHER_up_ref,
-                       (void (*)(void *))EVP_ASYM_CIPHER_free);
+                       evp_asym_cipher_up_ref,
+                       evp_asym_cipher_free);
 }
 
 

+ 64 - 64
libs/openssl/crypto/evp/bio_b64.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -103,9 +103,17 @@ static int b64_free(BIO *a)
     return 1;
 }
 
+/*
+ * Unless `BIO_FLAGS_BASE64_NO_NL` is set, this BIO ignores leading lines that
+ * aren't exclusively composed of valid Base64 characters (followed by <CRLF>
+ * or <LF>).  Once a valid Base64 line is found, `ctx->start` is set to 0 and
+ * lines are processed until EOF or the first line that contains invalid Base64
+ * characters.  In a nod to PEM, lines that start with a '-' (hyphen) are
+ * treated as a soft EOF, rather than an error.
+ */
 static int b64_read(BIO *b, char *out, int outl)
 {
-    int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
+    int ret = 0, i, ii, j, k, x, n, num, ret_code;
     BIO_B64_CTX *ctx;
     unsigned char *p, *q;
     BIO *next;
@@ -128,7 +136,7 @@ static int b64_read(BIO *b, char *out, int outl)
         EVP_DecodeInit(ctx->base64);
     }
 
-    /* First check if there are bytes decoded/encoded */
+    /* First check if there are buffered bytes already decoded */
     if (ctx->buf_len > 0) {
         OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
         i = ctx->buf_len - ctx->buf_off;
@@ -146,14 +154,17 @@ static int b64_read(BIO *b, char *out, int outl)
         }
     }
 
+    /* Restore any non-retriable error condition (ctx->cont < 0) */
+    ret_code = ctx->cont < 0 ? ctx->cont : 0;
+
     /*
-     * At this point, we have room of outl bytes and an empty buffer, so we
-     * should read in some more.
+     * At this point, we have room of outl bytes and an either an empty buffer,
+     * or outl == 0, so we'll attempt to read in some more.
      */
-
-    ret_code = 0;
     while (outl > 0) {
-        if (ctx->cont <= 0)
+        int again = ctx->cont;
+
+        if (again <= 0)
             break;
 
         i = BIO_read(next, &(ctx->tmp[ctx->tmp_len]),
@@ -164,18 +175,22 @@ static int b64_read(BIO *b, char *out, int outl)
 
             /* Should we continue next time we are called? */
             if (!BIO_should_retry(next)) {
-                ctx->cont = i;
-                /* If buffer empty break */
-                if (ctx->tmp_len == 0)
-                    break;
-                /* Fall through and process what we have */
-                else
-                    i = 0;
+                /* Incomplete final Base64 chunk in the decoder is an error */
+                if (ctx->tmp_len == 0) {
+                    if (EVP_DecodeFinal(ctx->base64, NULL, &num) < 0)
+                        ret_code = -1;
+                    EVP_DecodeInit(ctx->base64);
+                }
+                ctx->cont = ret_code;
             }
-            /* else we retry and add more data to buffer */
-            else
+            if (ctx->tmp_len == 0)
                 break;
+            /* Fall through and process what we have */
+            i = 0;
+            /* But don't loop to top-up even if the buffer is not full! */
+            again = 0;
         }
+
         i += ctx->tmp_len;
         ctx->tmp_len = i;
 
@@ -204,23 +219,23 @@ static int b64_read(BIO *b, char *out, int outl)
                 }
 
                 k = EVP_DecodeUpdate(ctx->base64, ctx->buf, &num, p, q - p);
-                if (k <= 0 && num == 0 && ctx->start) {
-                    EVP_DecodeInit(ctx->base64);
-                } else {
-                    if (p != ctx->tmp) {
-                        i -= p - ctx->tmp;
-                        for (x = 0; x < i; x++)
-                            ctx->tmp[x] = p[x];
-                    }
-                    EVP_DecodeInit(ctx->base64);
-                    ctx->start = 0;
-                    break;
+                EVP_DecodeInit(ctx->base64);
+                if (k <= 0 && num == 0) {
+                    p = q;
+                    continue;
+                }
+
+                ctx->start = 0;
+                if (p != ctx->tmp) {
+                    i -= p - ctx->tmp;
+                    for (x = 0; x < i; x++)
+                        ctx->tmp[x] = p[x];
                 }
-                p = q;
+                break;
             }
 
             /* we fell off the end without starting */
-            if (j == i && num == 0) {
+            if (ctx->start) {
                 /*
                  * Is this is one long chunk?, if so, keep on reading until a
                  * new line.
@@ -231,18 +246,29 @@ static int b64_read(BIO *b, char *out, int outl)
                         ctx->tmp_nl = 1;
                         ctx->tmp_len = 0;
                     }
-                } else if (p != q) { /* finished on a '\n' */
+                } else if (p != q) {
+                    /* Retain partial line at end of buffer */
                     n = q - p;
                     for (ii = 0; ii < n; ii++)
                         ctx->tmp[ii] = p[ii];
                     ctx->tmp_len = n;
+                } else {
+                    /* All we have is newline terminated non-start data */
+                    ctx->tmp_len = 0;
                 }
-                /* else finished on a '\n' */
-                continue;
+                /*
+                 * Try to read more if possible, otherwise we can't make
+                 * progress unless the underlying BIO is retriable and may
+                 * produce more data next time we're called.
+                 */
+                if (again > 0)
+                    continue;
+                else
+                    break;
             } else {
                 ctx->tmp_len = 0;
             }
-        } else if (i < B64_BLOCK_SIZE && ctx->cont > 0) {
+        } else if (i < B64_BLOCK_SIZE && again > 0) {
             /*
              * If buffer isn't full and we can retry then restart to read in
              * more data.
@@ -250,35 +276,9 @@ static int b64_read(BIO *b, char *out, int outl)
             continue;
         }
 
-        if ((BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) != 0) {
-            int z, jj;
-
-            jj = i & ~3;        /* process per 4 */
-            z = EVP_DecodeBlock(ctx->buf, ctx->tmp, jj);
-            if (jj > 2) {
-                if (ctx->tmp[jj - 1] == '=') {
-                    z--;
-                    if (ctx->tmp[jj - 2] == '=')
-                        z--;
-                }
-            }
-            /*
-             * z is now number of output bytes and jj is the number consumed
-             */
-            if (jj != i) {
-                memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
-                ctx->tmp_len = i - jj;
-            }
-            ctx->buf_len = 0;
-            if (z > 0) {
-                ctx->buf_len = z;
-            }
-            i = z;
-        } else {
-            i = EVP_DecodeUpdate(ctx->base64, ctx->buf, &ctx->buf_len,
-                                 ctx->tmp, i);
-            ctx->tmp_len = 0;
-        }
+        i = EVP_DecodeUpdate(ctx->base64, ctx->buf, &ctx->buf_len,
+                             ctx->tmp, i);
+        ctx->tmp_len = 0;
         /*
          * If eof or an error was signalled, then the condition
          * 'ctx->cont <= 0' will prevent b64_read() from reading
@@ -289,7 +289,7 @@ static int b64_read(BIO *b, char *out, int outl)
 
         ctx->buf_off = 0;
         if (i < 0) {
-            ret_code = 0;
+            ret_code = ctx->start ? 0 : i;
             ctx->buf_len = 0;
             break;
         }

+ 6 - 2
libs/openssl/crypto/evp/bio_ok.c

@@ -443,6 +443,8 @@ static int sig_out(BIO *b)
     md_size = EVP_MD_get_size(digest);
     md_data = EVP_MD_CTX_get0_md_data(md);
 
+    if (md_size <= 0)
+        goto berr;
     if (ctx->buf_len + 2 * md_size > OK_BLOCK_SIZE)
         return 1;
 
@@ -485,7 +487,7 @@ static int sig_in(BIO *b)
     if ((md = ctx->md) == NULL)
         goto berr;
     digest = EVP_MD_CTX_get0_md(md);
-    if ((md_size = EVP_MD_get_size(digest)) < 0)
+    if ((md_size = EVP_MD_get_size(digest)) <= 0)
         goto berr;
     md_data = EVP_MD_CTX_get0_md_data(md);
 
@@ -533,6 +535,8 @@ static int block_out(BIO *b)
     md = ctx->md;
     digest = EVP_MD_CTX_get0_md(md);
     md_size = EVP_MD_get_size(digest);
+    if (md_size <= 0)
+        goto berr;
 
     tl = ctx->buf_len - OK_BLOCK_BLOCK;
     ctx->buf[0] = (unsigned char)(tl >> 24);
@@ -563,7 +567,7 @@ static int block_in(BIO *b)
     ctx = BIO_get_data(b);
     md = ctx->md;
     md_size = EVP_MD_get_size(EVP_MD_CTX_get0_md(md));
-    if (md_size < 0)
+    if (md_size <= 0)
         goto berr;
 
     assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */

File diff suppressed because it is too large
+ 170 - 167
libs/openssl/crypto/evp/ctrl_params_translate.c


+ 3 - 4
libs/openssl/crypto/evp/dh_support.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2024 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
@@ -12,7 +12,7 @@
 #include "internal/nelem.h"
 #include "crypto/dh.h"
 
-typedef struct dh_name2id_st{
+typedef struct dh_name2id_st {
     const char *name;
     int id;
     int type;
@@ -28,8 +28,7 @@ typedef struct dh_name2id_st{
 # define TYPE_DHX   0
 #endif
 
-static const DH_GENTYPE_NAME2ID dhtype2id[] =
-{
+static const DH_GENTYPE_NAME2ID dhtype2id[] = {
     { "group", DH_PARAMGEN_TYPE_GROUP, TYPE_ANY },
     { "generator", DH_PARAMGEN_TYPE_GENERATOR, TYPE_DH },
     { "fips186_4", DH_PARAMGEN_TYPE_FIPS_186_4, TYPE_DHX },

+ 120 - 40
libs/openssl/crypto/evp/digest.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -20,6 +20,7 @@
 #include <openssl/params.h>
 #include <openssl/core_names.h>
 #include "internal/cryptlib.h"
+#include "internal/nelem.h"
 #include "internal/provider.h"
 #include "internal/core.h"
 #include "crypto/evp.h"
@@ -77,7 +78,6 @@ static int evp_md_ctx_reset_ex(EVP_MD_CTX *ctx, int keep_fetched)
     if (ctx == NULL)
         return 1;
 
-#ifndef FIPS_MODULE
     /*
      * pctx should be freed by the user of EVP_MD_CTX
      * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set
@@ -86,7 +86,6 @@ static int evp_md_ctx_reset_ex(EVP_MD_CTX *ctx, int keep_fetched)
         EVP_PKEY_CTX_free(ctx->pctx);
         ctx->pctx = NULL;
     }
-#endif
 
     evp_md_ctx_clear_digest(ctx, 0, keep_fetched);
     if (!keep_fetched)
@@ -396,6 +395,7 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
     if (ctx->pctx != NULL
             && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx)
             && ctx->pctx->op.sig.algctx != NULL) {
+#ifndef FIPS_MODULE
         /*
          * Prior to OpenSSL 3.0 EVP_DigestSignUpdate() and
          * EVP_DigestVerifyUpdate() were just macros for EVP_DigestUpdate().
@@ -408,6 +408,7 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
             return EVP_DigestSignUpdate(ctx, data, count);
         if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX)
             return EVP_DigestVerifyUpdate(ctx, data, count);
+#endif
         ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
         return 0;
     }
@@ -447,22 +448,13 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
     if (ctx->digest == NULL)
         return 0;
 
-    sz = EVP_MD_get_size(ctx->digest);
+    sz = EVP_MD_CTX_get_size(ctx);
     if (sz < 0)
         return 0;
     mdsize = sz;
     if (ctx->digest->prov == NULL)
         goto legacy;
 
-    if (ctx->digest->gettable_ctx_params != NULL) {
-        OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
-
-        params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE,
-                                                &mdsize);
-        if (!EVP_MD_CTX_get_params(ctx, params))
-            return 0;
-    }
-
     if (ctx->digest->dfinal == NULL) {
         ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
         return 0;
@@ -543,7 +535,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
     return ret;
 
 legacy:
-    if (ctx->digest->flags & EVP_MD_FLAG_XOF
+    if (EVP_MD_xof(ctx->digest)
         && size <= INT_MAX
         && ctx->digest->md_ctrl(ctx, EVP_MD_CTRL_XOF_LEN, (int)size, NULL)) {
         ret = ctx->digest->final(ctx, md);
@@ -625,23 +617,36 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
         return 0;
     }
 
-    evp_md_ctx_reset_ex(out, 1);
-    digest_change = (out->fetched_digest != in->fetched_digest);
-    if (digest_change && out->fetched_digest != NULL)
-        EVP_MD_free(out->fetched_digest);
-    *out = *in;
-    /* NULL out pointers in case of error */
-    out->pctx = NULL;
-    out->algctx = NULL;
+    if (out->digest == in->digest && in->digest->copyctx != NULL) {
 
-    if (digest_change && in->fetched_digest != NULL)
-        EVP_MD_up_ref(in->fetched_digest);
+        in->digest->copyctx(out->algctx, in->algctx);
 
-    if (in->algctx != NULL) {
-        out->algctx = in->digest->dupctx(in->algctx);
-        if (out->algctx == NULL) {
-            ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX);
+        EVP_PKEY_CTX_free(out->pctx);
+        out->pctx = NULL;
+        cleanup_old_md_data(out, 0);
+
+        out->flags = in->flags;
+        out->update = in->update;
+    } else {
+        evp_md_ctx_reset_ex(out, 1);
+        digest_change = (out->fetched_digest != in->fetched_digest);
+
+        if (digest_change && in->fetched_digest != NULL
+            && !EVP_MD_up_ref(in->fetched_digest))
             return 0;
+        if (digest_change && out->fetched_digest != NULL)
+            EVP_MD_free(out->fetched_digest);
+        *out = *in;
+        /* NULL out pointers in case of error */
+        out->pctx = NULL;
+        out->algctx = NULL;
+
+        if (in->algctx != NULL) {
+            out->algctx = in->digest->dupctx(in->algctx);
+            if (out->algctx == NULL) {
+                ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX);
+                return 0;
+            }
         }
     }
 
@@ -982,6 +987,11 @@ static int evp_md_cache_constants(EVP_MD *md)
     size_t mdsize = 0;
     OSSL_PARAM params[5];
 
+    /*
+     * Note that these parameters are 'constants' that are only set up
+     * during the EVP_MD_fetch(). For this reason the XOF functions set the
+     * md_size to 0, since the output size is unknown.
+     */
     params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, &blksz);
     params[1] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &mdsize);
     params[2] = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_XOF, &xof);
@@ -1021,16 +1031,14 @@ static void *evp_md_from_algorithm(int name_id,
     if (!evp_names_do_all(prov, name_id, set_legacy_nid, &md->type)
             || md->type == -1) {
         ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
-        EVP_MD_free(md);
-        return NULL;
+        goto err;
     }
 #endif
 
     md->name_id = name_id;
-    if ((md->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
-        EVP_MD_free(md);
-        return NULL;
-    }
+    if ((md->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
+        goto err;
+
     md->description = algodef->algorithm_description;
 
     for (; fns->function_id != 0; fns++) {
@@ -1106,6 +1114,11 @@ static void *evp_md_from_algorithm(int name_id,
                 md->gettable_ctx_params =
                     OSSL_FUNC_digest_gettable_ctx_params(fns);
             break;
+        case OSSL_FUNC_DIGEST_COPYCTX:
+            if (md->copyctx == NULL)
+                md->copyctx =
+                    OSSL_FUNC_digest_copyctx(fns);
+            break;
         }
     }
     if ((fncnt != 0 && fncnt != 5 && fncnt != 6)
@@ -1116,21 +1129,24 @@ static void *evp_md_from_algorithm(int name_id,
          * The "digest" function can standalone. We at least need one way to
          * generate digests.
          */
-        EVP_MD_free(md);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
+        goto err;
     }
+    if (prov != NULL && !ossl_provider_up_ref(prov))
+        goto err;
+
     md->prov = prov;
-    if (prov != NULL)
-        ossl_provider_up_ref(prov);
 
     if (!evp_md_cache_constants(md)) {
-        EVP_MD_free(md);
         ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED);
-        md = NULL;
+        goto err;
     }
 
     return md;
+
+err:
+    EVP_MD_free(md);
+    return NULL;
 }
 
 static int evp_md_up_ref(void *md)
@@ -1183,3 +1199,67 @@ void EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx,
                        (void (*)(void *, void *))fn, arg,
                        evp_md_from_algorithm, evp_md_up_ref, evp_md_free);
 }
+
+EVP_MD *evp_digest_fetch_from_prov(OSSL_PROVIDER *prov,
+                                   const char *algorithm,
+                                   const char *properties)
+{
+    return evp_generic_fetch_from_prov(prov, OSSL_OP_DIGEST,
+                                       algorithm, properties,
+                                       evp_md_from_algorithm,
+                                       evp_md_up_ref,
+                                       evp_md_free);
+}
+
+typedef struct {
+    int md_nid;
+    int hmac_nid;
+} ossl_hmacmd_pair;
+
+static const ossl_hmacmd_pair ossl_hmacmd_pairs[] = {
+    {NID_sha1, NID_hmacWithSHA1},
+    {NID_md5, NID_hmacWithMD5},
+    {NID_sha224, NID_hmacWithSHA224},
+    {NID_sha256, NID_hmacWithSHA256},
+    {NID_sha384, NID_hmacWithSHA384},
+    {NID_sha512, NID_hmacWithSHA512},
+    {NID_id_GostR3411_94, NID_id_HMACGostR3411_94},
+    {NID_id_GostR3411_2012_256, NID_id_tc26_hmac_gost_3411_2012_256},
+    {NID_id_GostR3411_2012_512, NID_id_tc26_hmac_gost_3411_2012_512},
+    {NID_sha3_224, NID_hmac_sha3_224},
+    {NID_sha3_256, NID_hmac_sha3_256},
+    {NID_sha3_384, NID_hmac_sha3_384},
+    {NID_sha3_512, NID_hmac_sha3_512},
+    {NID_sha512_224, NID_hmacWithSHA512_224},
+    {NID_sha512_256, NID_hmacWithSHA512_256}
+};
+
+int ossl_hmac2mdnid(int hmac_nid)
+{
+    int md_nid = NID_undef;
+    size_t i;
+
+    for (i = 0; i < OSSL_NELEM(ossl_hmacmd_pairs); i++) {
+        if (ossl_hmacmd_pairs[i].hmac_nid == hmac_nid) {
+            md_nid = ossl_hmacmd_pairs[i].md_nid;
+            break;
+        }
+    }
+
+    return md_nid;
+}
+
+int ossl_md2hmacnid(int md_nid)
+{
+    int hmac_nid = NID_undef;
+    size_t i;
+
+    for (i = 0; i < OSSL_NELEM(ossl_hmacmd_pairs); i++) {
+        if (ossl_hmacmd_pairs[i].md_nid == md_nid) {
+            hmac_nid = ossl_hmacmd_pairs[i].hmac_nid;
+            break;
+        }
+    }
+
+    return hmac_nid;
+}

+ 4 - 3
libs/openssl/crypto/evp/e_des3.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -312,8 +312,9 @@ const EVP_CIPHER *EVP_des_ede3(void)
 
 # include <openssl/sha.h>
 
-static const unsigned char wrap_iv[8] =
-    { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 };
+static const unsigned char wrap_iv[8] = {
+    0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05
+};
 
 static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
                            const unsigned char *in, size_t inl)

+ 52 - 14
libs/openssl/crypto/evp/encode.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -19,7 +19,7 @@ static unsigned char conv_ascii2bin(unsigned char a,
 static int evp_encodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
                                const unsigned char *f, int dlen);
 static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
-                               const unsigned char *f, int n);
+                               const unsigned char *f, int n, int eof);
 
 #ifndef CHARSET_EBCDIC
 # define conv_bin2ascii(a, table)       ((table)[(a)&0x3f])
@@ -369,14 +369,14 @@ int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
         }
 
         if (n == 64) {
-            decoded_len = evp_decodeblock_int(ctx, out, d, n);
+            decoded_len = evp_decodeblock_int(ctx, out, d, n, eof);
             n = 0;
-            if (decoded_len < 0 || eof > decoded_len) {
+            if (decoded_len < 0 || (decoded_len == 0 && eof > 0)) {
                 rv = -1;
                 goto end;
             }
-            ret += decoded_len - eof;
-            out += decoded_len - eof;
+            ret += decoded_len;
+            out += decoded_len;
         }
     }
 
@@ -388,13 +388,13 @@ int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
 tail:
     if (n > 0) {
         if ((n & 3) == 0) {
-            decoded_len = evp_decodeblock_int(ctx, out, d, n);
+            decoded_len = evp_decodeblock_int(ctx, out, d, n, eof);
             n = 0;
-            if (decoded_len < 0 || eof > decoded_len) {
+            if (decoded_len < 0 || (decoded_len == 0 && eof > 0)) {
                 rv = -1;
                 goto end;
             }
-            ret += (decoded_len - eof);
+            ret += decoded_len;
         } else if (seof) {
             /* EOF in the middle of a base64 block. */
             rv = -1;
@@ -411,12 +411,16 @@ end:
 }
 
 static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
-                               const unsigned char *f, int n)
+                               const unsigned char *f, int n,
+                               int eof)
 {
     int i, ret = 0, a, b, c, d;
     unsigned long l;
     const unsigned char *table;
 
+    if (eof < -1 || eof > 2)
+        return -1;
+
     if (ctx != NULL && (ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
         table = srpdata_ascii2bin;
     else
@@ -437,13 +441,16 @@ static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
 
     if (n % 4 != 0)
         return -1;
+    if (n == 0)
+        return 0;
 
-    for (i = 0; i < n; i += 4) {
+    /* all 4-byte blocks except the last one do not have padding. */
+    for (i = 0; i < n - 4; i += 4) {
         a = conv_ascii2bin(*(f++), table);
         b = conv_ascii2bin(*(f++), table);
         c = conv_ascii2bin(*(f++), table);
         d = conv_ascii2bin(*(f++), table);
-        if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80))
+        if ((a | b | c | d) & 0x80)
             return -1;
         l = ((((unsigned long)a) << 18L) |
              (((unsigned long)b) << 12L) |
@@ -453,12 +460,43 @@ static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
         *(t++) = (unsigned char)(l) & 0xff;
         ret += 3;
     }
+
+    /* process the last block that may have padding. */
+    a = conv_ascii2bin(*(f++), table);
+    b = conv_ascii2bin(*(f++), table);
+    c = conv_ascii2bin(*(f++), table);
+    d = conv_ascii2bin(*(f++), table);
+    if ((a | b | c | d) & 0x80)
+        return -1;
+    l = ((((unsigned long)a) << 18L) |
+         (((unsigned long)b) << 12L) |
+         (((unsigned long)c) << 6L) | (((unsigned long)d)));
+
+    if (eof == -1)
+        eof = (f[2] == '=') + (f[3] == '=');
+
+    switch (eof) {
+    case 2:
+        *(t++) = (unsigned char)(l >> 16L) & 0xff;
+        break;
+    case 1:
+        *(t++) = (unsigned char)(l >> 16L) & 0xff;
+        *(t++) = (unsigned char)(l >> 8L) & 0xff;
+        break;
+    case 0:
+        *(t++) = (unsigned char)(l >> 16L) & 0xff;
+        *(t++) = (unsigned char)(l >> 8L) & 0xff;
+        *(t++) = (unsigned char)(l) & 0xff;
+        break;
+    }
+    ret += 3 - eof;
+
     return ret;
 }
 
 int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
 {
-    return evp_decodeblock_int(NULL, t, f, n);
+    return evp_decodeblock_int(NULL, t, f, n, 0);
 }
 
 int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
@@ -467,7 +505,7 @@ int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
 
     *outl = 0;
     if (ctx->num != 0) {
-        i = evp_decodeblock_int(ctx, out, ctx->enc_data, ctx->num);
+        i = evp_decodeblock_int(ctx, out, ctx->enc_data, ctx->num, -1);
         if (i < 0)
             return -1;
         ctx->num = 0;

+ 402 - 24
libs/openssl/crypto/evp/evp_enc.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -93,6 +93,7 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
                                     const EVP_CIPHER *cipher,
                                     ENGINE *impl, const unsigned char *key,
                                     const unsigned char *iv, int enc,
+                                    uint8_t is_pipeline,
                                     const OSSL_PARAM params[])
 {
     int n;
@@ -119,6 +120,8 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
     }
 
     /* Code below to be removed when legacy support is dropped. */
+    if (is_pipeline)
+        goto nonlegacy;
 
 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
     /*
@@ -166,7 +169,7 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
     }
 
     /* Start of non-legacy code below */
-
+nonlegacy:
     /* Ensure a context left lying around from last time is cleared */
     if (cipher != NULL && ctx->cipher != NULL) {
         unsigned long flags = ctx->flags;
@@ -216,6 +219,12 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
         ctx->fetched_cipher = (EVP_CIPHER *)cipher;
     }
     ctx->cipher = cipher;
+
+    if (is_pipeline && !EVP_CIPHER_can_pipeline(cipher, enc)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_PIPELINE_NOT_SUPPORTED);
+        return 0;
+    }
+
     if (ctx->algctx == NULL) {
         ctx->algctx = ctx->cipher->newctx(ossl_provider_ctx(cipher->prov));
         if (ctx->algctx == NULL) {
@@ -248,7 +257,7 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
         OSSL_PARAM *q = param_lens;
         const OSSL_PARAM *p;
 
-        p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); 
+        p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
         if (p != NULL)
             memcpy(q++, p, sizeof(*q));
 
@@ -269,8 +278,22 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
     }
 #endif
 
+    if (is_pipeline)
+        return 1;
+
     if (enc) {
         if (ctx->cipher->einit == NULL) {
+            /*
+             * We still should be able to set the IV using the new API
+             * if the key is not specified and old API is not available
+             */
+            if (key == NULL && ctx->cipher->einit_skey != NULL) {
+                return ctx->cipher->einit_skey(ctx->algctx, NULL,
+                                               iv,
+                                               iv == NULL ? 0
+                                                          : EVP_CIPHER_CTX_get_iv_length(ctx),
+                                               params);
+            }
             ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
             return 0;
         }
@@ -286,6 +309,17 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
     }
 
     if (ctx->cipher->dinit == NULL) {
+        /*
+         * We still should be able to set the IV using the new API
+         * if the key is not specified and old API is not available
+         */
+        if (key == NULL && ctx->cipher->dinit_skey != NULL) {
+            return ctx->cipher->dinit_skey(ctx->algctx, NULL,
+                                           iv,
+                                           iv == NULL ? 0
+                                                      : EVP_CIPHER_CTX_get_iv_length(ctx),
+                                           params);
+        }
         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
         return 0;
     }
@@ -440,11 +474,168 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
     return 1;
 }
 
+/*
+ * This function is basically evp_cipher_init_internal without ENGINE support.
+ * They should be combined when engines are not supported any longer.
+ */
+static int evp_cipher_init_skey_internal(EVP_CIPHER_CTX *ctx,
+                                         const EVP_CIPHER *cipher,
+                                         const EVP_SKEY *skey,
+                                         const unsigned char *iv, size_t iv_len,
+                                         int enc, const OSSL_PARAM params[])
+{
+    int ret;
+
+    /*
+     * enc == 1 means we are encrypting.
+     * enc == 0 means we are decrypting.
+     * enc == -1 means, use the previously initialised value for encrypt/decrypt
+     */
+    if (enc == -1)
+        enc = ctx->encrypt;
+    else
+        ctx->encrypt = enc != 0;
+
+    if (cipher == NULL && ctx->cipher == NULL) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
+        return 0;
+    }
+
+    /*
+     * If there are engines involved then we throw an error
+     */
+    if (ctx->engine != NULL
+            || (cipher != NULL && cipher->origin == EVP_ORIG_METH)
+            || (cipher == NULL && ctx->cipher != NULL
+                && ctx->cipher->origin == EVP_ORIG_METH)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+        return 0;
+    }
+    /*
+     * Ensure a context left lying around from last time is cleared
+     * (legacy code)
+     */
+    if (cipher != NULL && ctx->cipher != NULL) {
+        if (ctx->cipher->cleanup != NULL && !ctx->cipher->cleanup(ctx))
+            return 0;
+        OPENSSL_clear_free(ctx->cipher_data, ctx->cipher->ctx_size);
+        ctx->cipher_data = NULL;
+    }
+
+    /* Ensure a context left lying around from last time is cleared */
+    if (cipher != NULL && ctx->cipher != NULL) {
+        unsigned long flags = ctx->flags;
+
+        EVP_CIPHER_CTX_reset(ctx);
+        /* Restore encrypt and flags */
+        ctx->encrypt = enc;
+        ctx->flags = flags;
+    }
+
+    if (cipher == NULL)
+        cipher = ctx->cipher;
+
+    if (cipher->prov == NULL) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+        return 0;
+    }
+
+    if (cipher != ctx->fetched_cipher) {
+        if (!EVP_CIPHER_up_ref((EVP_CIPHER *)cipher)) {
+            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+            return 0;
+        }
+        EVP_CIPHER_free(ctx->fetched_cipher);
+        /* Coverity false positive, the reference counting is confusing it */
+        /* coverity[use_after_free] */
+        ctx->fetched_cipher = (EVP_CIPHER *)cipher;
+    }
+    ctx->cipher = cipher;
+    if (ctx->algctx == NULL) {
+        ctx->algctx = ctx->cipher->newctx(ossl_provider_ctx(cipher->prov));
+        if (ctx->algctx == NULL) {
+            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+            return 0;
+        }
+    }
+
+    if (skey != NULL && ctx->cipher->prov != skey->skeymgmt->prov) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+        return 0;
+    }
+
+    if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0) {
+        /*
+         * If this ctx was already set up for no padding then we need to tell
+         * the new cipher about it.
+         */
+        if (!EVP_CIPHER_CTX_set_padding(ctx, 0))
+            return 0;
+    }
+
+    if (iv == NULL)
+        iv_len = 0;
+
+    /* We have a data managed via key management, using the new callbacks */
+    if (enc) {
+        if (ctx->cipher->einit_skey == NULL) {
+            /*
+             *  When skey is NULL, it's a multiple-step init as the current API does.
+             *  Otherwise we try to fallback for providers that do not support SKEYs.
+             */
+            const unsigned char *keydata = NULL;
+            size_t keylen = 0;
+
+            if (skey != NULL && !EVP_SKEY_get0_raw_key(skey, &keydata, &keylen)) {
+                ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+                return 0;
+            }
+
+            ret = ctx->cipher->einit(ctx->algctx, keydata, keylen,
+                                     iv, iv_len, params);
+        } else {
+            ret = ctx->cipher->einit_skey(ctx->algctx,
+                                          skey == NULL ? NULL : skey->keydata,
+                                          iv, iv_len, params);
+        }
+    } else {
+        if (ctx->cipher->dinit_skey == NULL) {
+            /*
+             *  When skey is NULL, it's a multiple-step init as the current API does.
+             *  Otherwise we try to fallback for providers that do not support SKEYs.
+             */
+            const unsigned char *keydata = NULL;
+            size_t keylen = 0;
+
+            if (skey != NULL && !EVP_SKEY_get0_raw_key(skey, &keydata, &keylen)) {
+                ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+                return 0;
+            }
+
+            ret = ctx->cipher->dinit(ctx->algctx, keydata, keylen,
+                                     iv, iv_len, params);
+        } else {
+            ret = ctx->cipher->dinit_skey(ctx->algctx,
+                                          skey == NULL ? NULL : skey->keydata,
+                                          iv, iv_len, params);
+        }
+    }
+
+    return ret;
+}
+
+int EVP_CipherInit_SKEY(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                        EVP_SKEY *skey, const unsigned char *iv, size_t iv_len,
+                        int enc, const OSSL_PARAM params[])
+{
+    return evp_cipher_init_skey_internal(ctx, cipher, skey, iv, iv_len, enc, params);
+}
+
 int EVP_CipherInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                        const unsigned char *key, const unsigned char *iv,
                        int enc, const OSSL_PARAM params[])
 {
-    return evp_cipher_init_internal(ctx, cipher, NULL, key, iv, enc, params);
+    return evp_cipher_init_internal(ctx, cipher, NULL, key, iv, enc, 0, params);
 }
 
 int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
@@ -452,14 +643,74 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
 {
     if (cipher != NULL)
         EVP_CIPHER_CTX_reset(ctx);
-    return evp_cipher_init_internal(ctx, cipher, NULL, key, iv, enc, NULL);
+    return evp_cipher_init_internal(ctx, cipher, NULL, key, iv, enc, 0, NULL);
 }
 
 int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                       ENGINE *impl, const unsigned char *key,
                       const unsigned char *iv, int enc)
 {
-    return evp_cipher_init_internal(ctx, cipher, impl, key, iv, enc, NULL);
+    return evp_cipher_init_internal(ctx, cipher, impl, key, iv, enc, 0, NULL);
+}
+
+int EVP_CipherPipelineEncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                                  const unsigned char *key, size_t keylen,
+                                  size_t numpipes,
+                                  const unsigned char **iv, size_t ivlen)
+{
+    if (numpipes > EVP_MAX_PIPES) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_TOO_MANY_PIPES);
+        return 0;
+    }
+
+    ctx->numpipes = numpipes;
+
+    if (!evp_cipher_init_internal(ctx, cipher, NULL, NULL, NULL, 1, 1,
+                                  NULL))
+        return 0;
+
+    if (ctx->cipher->p_einit == NULL) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+        return 0;
+    }
+
+    return ctx->cipher->p_einit(ctx->algctx,
+                                key,
+                                keylen,
+                                numpipes,
+                                iv,
+                                ivlen,
+                                NULL);
+}
+
+int EVP_CipherPipelineDecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                                  const unsigned char *key, size_t keylen,
+                                  size_t numpipes,
+                                  const unsigned char **iv, size_t ivlen)
+{
+    if (numpipes > EVP_MAX_PIPES) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_TOO_MANY_PIPES);
+        return 0;
+    }
+
+    ctx->numpipes = numpipes;
+
+    if (!evp_cipher_init_internal(ctx, cipher, NULL, NULL, NULL, 0, 1,
+                                  NULL))
+        return 0;
+
+    if (ctx->cipher->p_dinit == NULL) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+        return 0;
+    }
+
+    return ctx->cipher->p_dinit(ctx->algctx,
+                                key,
+                                keylen,
+                                numpipes,
+                                iv,
+                                ivlen,
+                                NULL);
 }
 
 int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
@@ -471,6 +722,41 @@ int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
         return EVP_DecryptUpdate(ctx, out, outl, in, inl);
 }
 
+int EVP_CipherPipelineUpdate(EVP_CIPHER_CTX *ctx,
+                             unsigned char **out, size_t *outl,
+                             const size_t *outsize,
+                             const unsigned char **in, const size_t *inl)
+{
+    size_t i;
+
+    if (ossl_unlikely(outl == NULL || inl == NULL)) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (ossl_unlikely(ctx->cipher == NULL)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
+        return 0;
+    }
+
+    if (ossl_unlikely(ctx->cipher->prov == NULL)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION);
+        return 0;
+    }
+
+    if (ossl_unlikely(ctx->cipher->p_cupdate == NULL)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
+        return 0;
+    }
+
+    for (i = 0; i < ctx->numpipes; i++)
+        outl[i] = 0;
+
+    return ctx->cipher->p_cupdate(ctx->algctx, ctx->numpipes,
+                                  out, outl, outsize,
+                                  in, inl);
+}
+
 int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 {
     if (ctx->encrypt)
@@ -487,6 +773,39 @@ int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
         return EVP_DecryptFinal(ctx, out, outl);
 }
 
+int EVP_CipherPipelineFinal(EVP_CIPHER_CTX *ctx,
+                            unsigned char **out, size_t *outl,
+                            const size_t *outsize)
+{
+    size_t i;
+
+    if (ossl_unlikely(outl == NULL)) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (ossl_unlikely(ctx->cipher == NULL)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
+        return 0;
+    }
+
+    if (ossl_unlikely(ctx->cipher->prov == NULL)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION);
+        return 0;
+    }
+
+    if (ossl_unlikely(ctx->cipher->p_cfinal == NULL)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
+        return 0;
+    }
+
+    for (i = 0; i < ctx->numpipes; i++)
+        outl[i] = 0;
+
+    return ctx->cipher->p_cfinal(ctx->algctx, ctx->numpipes,
+                                 out, outl, outsize);
+}
+
 int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                     const unsigned char *key, const unsigned char *iv)
 {
@@ -1034,8 +1353,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
         for (i = 0; i < n; i++)
             out[i] = ctx->final[i];
         *outl = n;
-    } else
-        *outl = 0;
+    }
     return 1;
 }
 
@@ -1568,7 +1886,7 @@ static void *evp_cipher_from_algorithm(const int name_id,
 {
     const OSSL_DISPATCH *fns = algodef->implementation;
     EVP_CIPHER *cipher = NULL;
-    int fnciphcnt = 0, fnctxcnt = 0;
+    int fnciphcnt = 0, encinit = 0, decinit = 0, fnpipecnt = 0, fnctxcnt = 0;
 
     if ((cipher = evp_cipher_new()) == NULL) {
         ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
@@ -1580,16 +1898,14 @@ static void *evp_cipher_from_algorithm(const int name_id,
     if (!evp_names_do_all(prov, name_id, set_legacy_nid, &cipher->nid)
             || cipher->nid == -1) {
         ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
-        EVP_CIPHER_free(cipher);
-        return NULL;
+        goto err;
     }
 #endif
 
     cipher->name_id = name_id;
-    if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
-        EVP_CIPHER_free(cipher);
-        return NULL;
-    }
+    if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
+        goto err;
+
     cipher->description = algodef->algorithm_description;
 
     for (; fns->function_id != 0; fns++) {
@@ -1604,13 +1920,25 @@ static void *evp_cipher_from_algorithm(const int name_id,
             if (cipher->einit != NULL)
                 break;
             cipher->einit = OSSL_FUNC_cipher_encrypt_init(fns);
-            fnciphcnt++;
+            encinit = 1;
             break;
         case OSSL_FUNC_CIPHER_DECRYPT_INIT:
             if (cipher->dinit != NULL)
                 break;
             cipher->dinit = OSSL_FUNC_cipher_decrypt_init(fns);
-            fnciphcnt++;
+            decinit = 1;
+            break;
+        case OSSL_FUNC_CIPHER_ENCRYPT_SKEY_INIT:
+            if (cipher->einit_skey != NULL)
+                break;
+            cipher->einit_skey = OSSL_FUNC_cipher_encrypt_skey_init(fns);
+            encinit = 1;
+            break;
+        case OSSL_FUNC_CIPHER_DECRYPT_SKEY_INIT:
+            if (cipher->dinit_skey != NULL)
+                break;
+            cipher->dinit_skey = OSSL_FUNC_cipher_decrypt_skey_init(fns);
+            decinit = 1;
             break;
         case OSSL_FUNC_CIPHER_UPDATE:
             if (cipher->cupdate != NULL)
@@ -1629,6 +1957,30 @@ static void *evp_cipher_from_algorithm(const int name_id,
                 break;
             cipher->ccipher = OSSL_FUNC_cipher_cipher(fns);
             break;
+        case OSSL_FUNC_CIPHER_PIPELINE_ENCRYPT_INIT:
+            if (cipher->p_einit != NULL)
+                break;
+            cipher->p_einit = OSSL_FUNC_cipher_pipeline_encrypt_init(fns);
+            fnpipecnt++;
+            break;
+        case OSSL_FUNC_CIPHER_PIPELINE_DECRYPT_INIT:
+            if (cipher->p_dinit != NULL)
+                break;
+            cipher->p_dinit = OSSL_FUNC_cipher_pipeline_decrypt_init(fns);
+            fnpipecnt++;
+            break;
+        case OSSL_FUNC_CIPHER_PIPELINE_UPDATE:
+            if (cipher->p_cupdate != NULL)
+                break;
+            cipher->p_cupdate = OSSL_FUNC_cipher_pipeline_update(fns);
+            fnpipecnt++;
+            break;
+        case OSSL_FUNC_CIPHER_PIPELINE_FINAL:
+            if (cipher->p_cfinal != NULL)
+                break;
+            cipher->p_cfinal = OSSL_FUNC_cipher_pipeline_final(fns);
+            fnpipecnt++;
+            break;
         case OSSL_FUNC_CIPHER_FREECTX:
             if (cipher->freectx != NULL)
                 break;
@@ -1674,8 +2026,11 @@ static void *evp_cipher_from_algorithm(const int name_id,
             break;
         }
     }
+    fnciphcnt += encinit + decinit;
     if ((fnciphcnt != 0 && fnciphcnt != 3 && fnciphcnt != 4)
-            || (fnciphcnt == 0 && cipher->ccipher == NULL)
+            || (fnciphcnt == 0 && cipher->ccipher == NULL && fnpipecnt == 0)
+            || (fnpipecnt != 0 && (fnpipecnt < 3 || cipher->p_cupdate == NULL
+                                   || cipher->p_cfinal == NULL))
             || fnctxcnt != 2) {
         /*
          * In order to be a consistent set of functions we must have at least
@@ -1683,21 +2038,24 @@ static void *evp_cipher_from_algorithm(const int name_id,
          * functions, or a single "cipher" function. In all cases we need both
          * the "newctx" and "freectx" functions.
          */
-        EVP_CIPHER_free(cipher);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
+        goto err;
     }
+    if (prov != NULL && !ossl_provider_up_ref(prov))
+        goto err;
+
     cipher->prov = prov;
-    if (prov != NULL)
-        ossl_provider_up_ref(prov);
 
     if (!evp_cipher_cache_constants(cipher)) {
-        EVP_CIPHER_free(cipher);
         ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED);
-        cipher = NULL;
+        goto err;
     }
 
     return cipher;
+
+err:
+    EVP_CIPHER_free(cipher);
+    return NULL;
 }
 
 static int evp_cipher_up_ref(void *cipher)
@@ -1721,6 +2079,26 @@ EVP_CIPHER *EVP_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
     return cipher;
 }
 
+EVP_CIPHER *evp_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
+                                       const char *algorithm,
+                                       const char *properties)
+{
+    return evp_generic_fetch_from_prov(prov, OSSL_OP_CIPHER,
+                                       algorithm, properties,
+                                       evp_cipher_from_algorithm,
+                                       evp_cipher_up_ref,
+                                       evp_cipher_free);
+}
+
+int EVP_CIPHER_can_pipeline(const EVP_CIPHER *cipher, int enc)
+{
+    if (((enc && cipher->p_einit != NULL) || (!enc && cipher->p_dinit != NULL))
+        && cipher->p_cupdate != NULL && cipher->p_cfinal != NULL)
+        return 1;
+
+    return 0;
+}
+
 int EVP_CIPHER_up_ref(EVP_CIPHER *cipher)
 {
     int ref = 0;

+ 92 - 71
libs/openssl/crypto/evp/evp_err.c

@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -16,150 +16,171 @@
 
 static const ERR_STRING_DATA EVP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_AES_KEY_SETUP_FAILED),
-    "aes key setup failed"},
+     "aes key setup failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ARIA_KEY_SETUP_FAILED),
-    "aria key setup failed"},
+     "aria key setup failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_ALGORITHM_NAME), "bad algorithm name"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT), "bad decrypt"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_KEY_LENGTH), "bad key length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CACHE_CONSTANTS_FAILED),
-    "cache constants failed"},
+     "cache constants failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED),
-    "camellia key setup failed"},
+     "camellia key setup failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_GET_PARAMETERS),
-    "cannot get parameters"},
+     "cannot get parameters"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_SET_PARAMETERS),
-    "cannot set parameters"},
+     "cannot set parameters"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_NOT_GCM_MODE),
-    "cipher not gcm mode"},
+     "cipher not gcm mode"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_PARAMETER_ERROR),
-    "cipher parameter error"},
+     "cipher parameter error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COMMAND_NOT_SUPPORTED),
-    "command not supported"},
+     "command not supported"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CONFLICTING_ALGORITHM_NAME),
-    "conflicting algorithm name"},
+     "conflicting algorithm name"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COPY_ERROR), "copy error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CTRL_NOT_IMPLEMENTED),
-    "ctrl not implemented"},
+     "ctrl not implemented"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),
-    "ctrl operation not implemented"},
+     "ctrl operation not implemented"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),
-    "data not multiple of block length"},
+     "data not multiple of block length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR), "decode error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DEFAULT_QUERY_PARSE_ERROR),
-    "default query parse error"},
+     "default query parse error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_KEY_TYPES),
-    "different key types"},
+     "different key types"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS),
-    "different parameters"},
+     "different parameters"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_LOADING_SECTION),
-    "error loading section"},
+     "error loading section"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_HMAC_KEY),
-    "expecting an hmac key"},
+     "expecting an hmac key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY),
-    "expecting an rsa key"},
+     "expecting an rsa key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DSA_KEY),
-    "expecting a dsa key"},
+     "expecting a dsa key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_ECX_KEY),
-    "expecting an ecx key"},
+     "expecting an ecx key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_EC_KEY), "expecting an ec key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_POLY1305_KEY),
-    "expecting a poly1305 key"},
+     "expecting a poly1305 key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_SIPHASH_KEY),
-    "expecting a siphash key"},
+     "expecting a siphash key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FINAL_ERROR), "final error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GENERATE_ERROR), "generate error"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GETTING_ALGORITHMIDENTIFIER_NOT_SUPPORTED),
+     "getting AlgorithmIdentifier not supported"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GET_RAW_KEY_FAILED), "get raw key failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_SCRYPT_PARAMETERS),
-    "illegal scrypt parameters"},
+     "illegal scrypt parameters"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS),
-    "inaccessible domain parameters"},
+     "inaccessible domain parameters"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_KEY), "inaccessible key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INITIALIZATION_ERROR),
-    "initialization error"},
+     "initialization error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INPUT_NOT_INITIALIZED),
-    "input not initialized"},
+     "input not initialized"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_CUSTOM_LENGTH),
-    "invalid custom length"},
+     "invalid custom length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST), "invalid digest"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_IV_LENGTH), "invalid iv length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_LENGTH), "invalid length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_NULL_ALGORITHM),
-    "invalid null algorithm"},
+     "invalid null algorithm"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PROVIDER_FUNCTIONS),
-    "invalid provider functions"},
+     "invalid provider functions"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH),
-    "invalid salt length"},
+     "invalid salt length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SECRET_LENGTH),
-    "invalid secret length"},
+     "invalid secret length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SEED_LENGTH),
-    "invalid seed length"},
+     "invalid seed length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_VALUE), "invalid value"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYMGMT_EXPORT_FAILURE),
-    "keymgmt export failure"},
+     "keymgmt export failure"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_LOCKING_NOT_SUPPORTED),
-    "locking not supported"},
+     "locking not supported"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MEMORY_LIMIT_EXCEEDED),
-    "memory limit exceeded"},
+     "memory limit exceeded"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MESSAGE_DIGEST_IS_NULL),
-    "message digest is null"},
+     "message digest is null"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_METHOD_NOT_SUPPORTED),
-    "method not supported"},
+     "method not supported"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MISSING_PARAMETERS), "missing parameters"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NOT_ABLE_TO_COPY_CTX),
-    "not able to copy ctx"},
+     "not able to copy ctx"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NOT_XOF_OR_INVALID_LENGTH),
-    "not XOF or invalid length"},
+     "not XOF or invalid length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_CIPHER_SET), "no cipher set"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "no default digest"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DIGEST_SET), "no digest set"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_IMPORT_FUNCTION), "no import function"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_AVAILABLE),
-    "no keymgmt available"},
+     "no keymgmt available"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_PRESENT), "no keymgmt present"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEY_SET), "no key set"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_OPERATION_SET), "no operation set"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NULL_MAC_PKEY_CTX), "null mac pkey ctx"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ONLY_ONESHOT_SUPPORTED),
-    "only oneshot supported"},
+     "only oneshot supported"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_INITIALIZED),
-    "operation not initialized"},
+     "operation not initialized"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
-    "operation not supported for this keytype"},
+     "operation not supported for this keytype"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_SIGNATURE_TYPE),
+     "operation not supported for this signature type"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OUTPUT_WOULD_OVERFLOW),
-    "output would overflow"},
+     "output would overflow"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARAMETER_TOO_LARGE),
-    "parameter too large"},
+     "parameter too large"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING),
-    "partially overlapping buffers"},
+     "partially overlapping buffers"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PBKDF2_ERROR), "pbkdf2 error"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PIPELINE_NOT_SUPPORTED),
+     "pipeline not supported"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED),
-    "pkey application asn1 method already registered"},
+     "pkey application asn1 method already registered"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_DECODE_ERROR),
-    "private key decode error"},
+     "private key decode error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_ENCODE_ERROR),
-    "private key encode error"},
+     "private key encode error"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE),
+     "provider asym cipher failure"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED),
+     "provider asym cipher not supported"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_KEYMGMT_FAILURE),
+     "provider keymgmt failure"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED),
+     "provider keymgmt not supported"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_SIGNATURE_FAILURE),
+     "provider signature failure"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED),
+     "provider signature not supported"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SETTING_XOF_FAILED), "setting xof failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SET_DEFAULT_PROPERTY_FAILURE),
-    "set default property failure"},
+     "set default property failure"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SIGNATURE_TYPE_AND_KEY_TYPE_INCOMPATIBLE),
+     "signature type and key type incompatible"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_TOO_MANY_PIPES), "too many pipes"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_TOO_MANY_RECORDS), "too many records"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_ENABLE_LOCKING),
-    "unable to enable locking"},
+     "unable to enable locking"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE),
-    "unable to get maximum request size"},
+     "unable to get maximum request size"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH),
-    "unable to get random strength"},
+     "unable to get random strength"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_LOCK_CONTEXT),
-    "unable to lock context"},
+     "unable to lock context"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_SET_CALLBACKS),
-    "unable to set callbacks"},
+     "unable to set callbacks"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_BITS), "unknown bits"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_CIPHER), "unknown cipher"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "unknown digest"},
@@ -167,36 +188,36 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_MAX_SIZE), "unknown max size"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_OPTION), "unknown option"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_PBE_ALGORITHM),
-    "unknown pbe algorithm"},
+     "unknown pbe algorithm"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_SECURITY_BITS),
-    "unknown security bits"},
+     "unknown security bits"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_ALGORITHM),
-    "unsupported algorithm"},
+     "unsupported algorithm"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEYLENGTH),
-    "unsupported keylength"},
+     "unsupported keylength"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),
-    "unsupported key derivation function"},
+     "unsupported key derivation function"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_SIZE),
-    "unsupported key size"},
+     "unsupported key size"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_TYPE),
-    "unsupported key type"},
+     "unsupported key type"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS),
-    "unsupported number of rounds"},
+     "unsupported number of rounds"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PRF), "unsupported prf"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM),
-    "unsupported private key algorithm"},
+     "unsupported private key algorithm"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_SALT_TYPE),
-    "unsupported salt type"},
+     "unsupported salt type"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UPDATE_ERROR), "update error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRAP_MODE_NOT_ALLOWED),
-    "wrap mode not allowed"},
+     "wrap mode not allowed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_FINAL_BLOCK_LENGTH),
-    "wrong final block length"},
+     "wrong final block length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE),
-    "xts data unit is too large"},
+     "xts data unit is too large"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DUPLICATED_KEYS),
-    "xts duplicated keys"},
+     "xts duplicated keys"},
     {0, NULL}
 };
 

+ 33 - 3
libs/openssl/crypto/evp/evp_fetch.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -48,13 +48,18 @@ static void *get_tmp_evp_method_store(void *data)
 {
     struct evp_method_data_st *methdata = data;
 
-    if (methdata->tmp_store == NULL)
+    if (methdata->tmp_store == NULL) {
         methdata->tmp_store = ossl_method_store_new(methdata->libctx);
+        OSSL_TRACE1(QUERY, "Allocating a new tmp_store %p\n", (void *)methdata->tmp_store);
+    } else {
+        OSSL_TRACE1(QUERY, "Using the existing tmp_store %p\n", (void *)methdata->tmp_store);
+    }
     return methdata->tmp_store;
 }
 
  static void dealloc_tmp_evp_method_store(void *store)
 {
+    OSSL_TRACE1(QUERY, "Deallocating the tmp_store %p\n", store);
     if (store != NULL)
         ossl_method_store_free(store);
 }
@@ -184,10 +189,15 @@ static int put_evp_method_in_store(void *store, void *method,
         || (meth_id = evp_method_id(name_id, methdata->operation_id)) == 0)
         return 0;
 
+    OSSL_TRACE1(QUERY, "put_evp_method_in_store: original store: %p\n", store);
     if (store == NULL
         && (store = get_evp_method_store(methdata->libctx)) == NULL)
         return 0;
 
+    OSSL_TRACE5(QUERY,
+                "put_evp_method_in_store: "
+                "store: %p, names: %s, operation_id %d, method_id: %d, properties: %s\n",
+                store, names, methdata->operation_id, meth_id, propdef ? propdef : "<null>");
     return ossl_method_store_add(store, prov, meth_id, propdef, method,
                                  methdata->refcnt_up_method,
                                  methdata->destruct_method);
@@ -240,7 +250,7 @@ static void destruct_evp_method(void *method, void *data)
 static void *
 inner_evp_generic_fetch(struct evp_method_data_st *methdata,
                         OSSL_PROVIDER *prov, int operation_id,
-                        const char *name, const char *properties,
+                        const char *name, ossl_unused const char *properties,
                         void *(*new_method)(int name_id,
                                             const OSSL_ALGORITHM *algodef,
                                             OSSL_PROVIDER *prov),
@@ -249,7 +259,17 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
 {
     OSSL_METHOD_STORE *store = get_evp_method_store(methdata->libctx);
     OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
+#ifdef FIPS_MODULE
+    /*
+     * The FIPS provider has its own internal library context where only it
+     * is loaded.  Consequently, property queries aren't relevant because
+     * there is only one fetchable algorithm and it is assumed that the
+     * FIPS-ness is handled by the using algorithm.
+     */
+    const char *const propq = "";
+#else
     const char *const propq = properties != NULL ? properties : "";
+#endif  /* FIPS_MODULE */
     uint32_t meth_id = 0;
     void *method = NULL;
     int unsupported, name_id;
@@ -357,6 +377,11 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
                        ossl_lib_ctx_get_descriptor(methdata->libctx),
                        name == NULL ? "<null>" : name, name_id,
                        properties == NULL ? "<null>" : properties);
+    } else {
+        OSSL_TRACE4(QUERY, "%s, Algorithm (%s : %d), Properties (%s)\n",
+                    ossl_lib_ctx_get_descriptor(methdata->libctx),
+                    name == NULL ? "<null>" : name, name_id,
+                    properties == NULL ? "<null>" : properties);
     }
 
     return method;
@@ -581,6 +606,11 @@ char *evp_get_global_properties_str(OSSL_LIB_CTX *libctx, int loadconfig)
     return propstr;
 }
 
+char *EVP_get1_default_properties(OSSL_LIB_CTX *libctx)
+{
+    return evp_get_global_properties_str(libctx, ossl_lib_ctx_is_global_default(libctx));
+}
+
 struct filter_data_st {
     int operation_id;
     void (*user_fn)(void *method, void *arg);

+ 298 - 53
libs/openssl/crypto/evp/evp_lib.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -17,6 +17,7 @@
 #include <string.h>
 #include "internal/cryptlib.h"
 #include <openssl/evp.h>
+#include <openssl/x509.h>
 #include <openssl/objects.h>
 #include <openssl/params.h>
 #include <openssl/core_names.h>
@@ -127,37 +128,13 @@ int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
             ret = EVP_CIPHER_set_asn1_iv(c, type);
         }
     } else if (cipher->prov != NULL) {
-        OSSL_PARAM params[3], *p = params;
-        unsigned char *der = NULL, *derp;
+        /* We cheat, there's no need for an object ID for this use */
+        X509_ALGOR alg;
 
-        /*
-         * We make two passes, the first to get the appropriate buffer size,
-         * and the second to get the actual value.
-         */
-        *p++ = OSSL_PARAM_construct_octet_string(
-                       OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS,
-                       NULL, 0);
-        *p = OSSL_PARAM_construct_end();
+        alg.algorithm = NULL;
+        alg.parameter = type;
 
-        if (!EVP_CIPHER_CTX_get_params(c, params))
-            goto err;
-
-        /* ... but, we should get a return size too! */
-        if (OSSL_PARAM_modified(params)
-            && params[0].return_size != 0
-            && (der = OPENSSL_malloc(params[0].return_size)) != NULL) {
-            params[0].data = der;
-            params[0].data_size = params[0].return_size;
-            OSSL_PARAM_set_all_unmodified(params);
-            derp = der;
-            if (EVP_CIPHER_CTX_get_params(c, params)
-                && OSSL_PARAM_modified(params)
-                && d2i_ASN1_TYPE(&type, (const unsigned char **)&derp,
-                                 params[0].return_size) != NULL) {
-                ret = 1;
-            }
-            OPENSSL_free(der);
-        }
+        ret = EVP_CIPHER_CTX_get_algor_params(c, &alg);
     } else {
         ret = -2;
     }
@@ -220,20 +197,13 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
             ret = EVP_CIPHER_get_asn1_iv(c, type) >= 0 ? 1 : -1;
         }
     } else if (cipher->prov != NULL) {
-        OSSL_PARAM params[3], *p = params;
-        unsigned char *der = NULL;
-        int derl = -1;
-
-        if ((derl = i2d_ASN1_TYPE(type, &der)) >= 0) {
-            *p++ =
-                OSSL_PARAM_construct_octet_string(
-                        OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS,
-                        der, (size_t)derl);
-            *p = OSSL_PARAM_construct_end();
-            if (EVP_CIPHER_CTX_set_params(c, params))
-                ret = 1;
-            OPENSSL_free(der);
-        }
+        /* We cheat, there's no need for an object ID for this use */
+        X509_ALGOR alg;
+
+        alg.algorithm = NULL;
+        alg.parameter = type;
+
+        ret = EVP_CIPHER_CTX_set_algor_params(c, &alg);
     } else {
         ret = -2;
     }
@@ -401,7 +371,7 @@ int EVP_CIPHER_get_block_size(const EVP_CIPHER *cipher)
 
 int EVP_CIPHER_CTX_get_block_size(const EVP_CIPHER_CTX *ctx)
 {
-    return EVP_CIPHER_get_block_size(ctx->cipher);
+    return (ctx == NULL) ? 0 : EVP_CIPHER_get_block_size(ctx->cipher);
 }
 
 int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
@@ -670,6 +640,9 @@ int EVP_CIPHER_get_key_length(const EVP_CIPHER *cipher)
 
 int EVP_CIPHER_CTX_get_key_length(const EVP_CIPHER_CTX *ctx)
 {
+    if (ctx->cipher == NULL)
+        return 0;
+
     if (ctx->key_len <= 0 && ctx->cipher->prov != NULL) {
         int ok;
         OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
@@ -841,6 +814,11 @@ int EVP_MD_get_size(const EVP_MD *md)
     return md->md_size;
 }
 
+int EVP_MD_xof(const EVP_MD *md)
+{
+    return md != NULL && ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0);
+}
+
 unsigned long EVP_MD_get_flags(const EVP_MD *md)
 {
     return md->flags;
@@ -1055,6 +1033,34 @@ EVP_MD *EVP_MD_CTX_get1_md(EVP_MD_CTX *ctx)
     return md;
 }
 
+int EVP_MD_CTX_get_size_ex(const EVP_MD_CTX *ctx)
+{
+    EVP_MD_CTX *c = (EVP_MD_CTX *)ctx;
+    const OSSL_PARAM *gettables;
+
+    gettables = EVP_MD_CTX_gettable_params(c);
+    if (gettables != NULL
+            && OSSL_PARAM_locate_const(gettables,
+                                       OSSL_DIGEST_PARAM_SIZE) != NULL) {
+        OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+        size_t sz = 0;
+
+        /*
+         * For XOF's EVP_MD_get_size() returns 0
+         * So try to get the xoflen instead. This will return -1 if the
+         * xof length has not been set.
+         */
+        params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &sz);
+        if (EVP_MD_CTX_get_params(c, params) != 1
+                || sz == SIZE_MAX
+                || sz == 0)
+            return -1;
+        return sz;
+    }
+    /* Normal digests have a constant fixed size output */
+    return EVP_MD_get_size(EVP_MD_CTX_get0_md(ctx));
+}
+
 EVP_PKEY_CTX *EVP_MD_CTX_get_pkey_ctx(const EVP_MD_CTX *ctx)
 {
     return ctx->pctx;
@@ -1187,6 +1193,7 @@ int EVP_PKEY_CTX_get_group_name(EVP_PKEY_CTX *ctx, char *name, size_t namelen)
         return -1;
     return 1;
 }
+#endif  /* !FIPS_MODULE */
 
 /*
  * evp_pkey_keygen() abstracts from the explicit use of B<EVP_PKEY_CTX>
@@ -1230,19 +1237,257 @@ EVP_PKEY *EVP_PKEY_Q_keygen(OSSL_LIB_CTX *libctx, const char *propq,
         name = va_arg(args, char *);
         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
                                                      name, 0);
-    } else if (OPENSSL_strcasecmp(type, "ED25519") != 0
-               && OPENSSL_strcasecmp(type, "X25519") != 0
-               && OPENSSL_strcasecmp(type, "ED448") != 0
-               && OPENSSL_strcasecmp(type, "X448") != 0
-               && OPENSSL_strcasecmp(type, "SM2") != 0) {
-        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT);
-        goto end;
     }
+
     ret = evp_pkey_keygen(libctx, type, propq, params);
 
- end:
     va_end(args);
     return ret;
 }
 
+#if !defined(FIPS_MODULE)
+int EVP_CIPHER_CTX_set_algor_params(EVP_CIPHER_CTX *ctx, const X509_ALGOR *alg)
+{
+    int ret = -1;                /* Assume the worst */
+    unsigned char *der = NULL;
+    int derl = -1;
+
+    if ((derl = i2d_ASN1_TYPE(alg->parameter, &der)) >= 0) {
+        const char *k_old = OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS_OLD;
+        const char *k_new = OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS;
+        OSSL_PARAM params[3];
+
+        /*
+         * Passing the same data with both the old (deprecated) and the
+         * new AlgID parameters OSSL_PARAM key.
+         */
+        params[0] = OSSL_PARAM_construct_octet_string(k_old, der, (size_t)derl);
+        params[1] = OSSL_PARAM_construct_octet_string(k_new, der, (size_t)derl);
+        params[2] = OSSL_PARAM_construct_end();
+        ret = EVP_CIPHER_CTX_set_params(ctx, params);
+    }
+    OPENSSL_free(der);
+    return ret;
+}
+
+int EVP_CIPHER_CTX_get_algor_params(EVP_CIPHER_CTX *ctx, X509_ALGOR *alg)
+{
+    int ret = -1;                /* Assume the worst */
+    unsigned char *der = NULL;
+    size_t derl;
+    ASN1_TYPE *type = NULL;
+    int i = -1;
+    const char *k_old = OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS_OLD;
+    const char *k_new = OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS;
+    const char *derk;
+    OSSL_PARAM params[3];
+
+    /*
+     * We make two passes, the first to get the appropriate buffer size,
+     * and the second to get the actual value.
+     * Also, using both the old (deprecated) and the new AlgID parameters
+     * OSSL_PARAM key, and using whichever the provider responds to.
+     * Should the provider respond on both, the new key takes priority.
+     */
+    params[0] = OSSL_PARAM_construct_octet_string(k_old, NULL, 0);
+    params[1] = OSSL_PARAM_construct_octet_string(k_new, NULL, 0);
+    params[2] = OSSL_PARAM_construct_end();
+
+    if (!EVP_CIPHER_CTX_get_params(ctx, params))
+        goto err;
+
+    /* ... but, we should get a return size too! */
+    if (OSSL_PARAM_modified(&params[0]) && params[0].return_size != 0)
+        i = 0;
+    if (OSSL_PARAM_modified(&params[1]) && params[1].return_size != 0)
+        i = 1;
+    if (i < 0)
+        goto err;
+
+    /*
+     * If alg->parameter is non-NULL, it will be changed by d2i_ASN1_TYPE()
+     * below.  If it is NULL, the d2i_ASN1_TYPE() call will allocate new
+     * space for it.  Either way, alg->parameter can be safely assigned
+     * with type after the d2i_ASN1_TYPE() call, with the safety that it
+     * will be ok.
+     */
+    type = alg->parameter;
+
+    derk = params[i].key;
+    derl = params[i].return_size;
+    if ((der = OPENSSL_malloc(derl)) != NULL) {
+        unsigned char *derp = der;
+
+        params[i] = OSSL_PARAM_construct_octet_string(derk, der, derl);
+        if (EVP_CIPHER_CTX_get_params(ctx, params)
+            && OSSL_PARAM_modified(&params[i])
+            && d2i_ASN1_TYPE(&type, (const unsigned char **)&derp,
+                             (int)derl) != NULL) {
+            /*
+             * Don't free alg->parameter, see comment further up.
+             * Worst case, alg->parameter gets assigned its own value.
+             */
+            alg->parameter = type;
+            ret = 1;
+        }
+    }
+ err:
+    OPENSSL_free(der);
+    return ret;
+}
+
+int EVP_CIPHER_CTX_get_algor(EVP_CIPHER_CTX *ctx, X509_ALGOR **alg)
+{
+    int ret = -1;                /* Assume the worst */
+    OSSL_PARAM params[2];
+    size_t aid_len = 0;
+    const char *k_aid = OSSL_SIGNATURE_PARAM_ALGORITHM_ID;
+
+    params[0] = OSSL_PARAM_construct_octet_string(k_aid, NULL, 0);
+    params[1] = OSSL_PARAM_construct_end();
+
+    if (EVP_CIPHER_CTX_get_params(ctx, params) <= 0)
+        goto err;
+
+    if (OSSL_PARAM_modified(&params[0]))
+        aid_len = params[0].return_size;
+    if (aid_len == 0) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_GETTING_ALGORITHMIDENTIFIER_NOT_SUPPORTED);
+        ret = -2;
+        goto err;
+    }
+    if (alg != NULL) {
+        unsigned char *aid = NULL;
+        const unsigned char *pp = NULL;
+
+        if ((aid = OPENSSL_malloc(aid_len)) != NULL) {
+            params[0] = OSSL_PARAM_construct_octet_string(k_aid, aid, aid_len);
+            pp = aid;
+            if (EVP_CIPHER_CTX_get_params(ctx, params)
+                && OSSL_PARAM_modified(&params[0])
+                && d2i_X509_ALGOR(alg, &pp, aid_len) != NULL)
+                ret = 1;
+        }
+        OPENSSL_free(aid);
+    }
+ err:
+    return ret;
+}
+
+int EVP_PKEY_CTX_set_algor_params(EVP_PKEY_CTX *ctx, const X509_ALGOR *alg)
+{
+    int ret = -1;                /* Assume the worst */
+    unsigned char *der = NULL;
+    int derl = -1;
+
+    if ((derl = i2d_ASN1_TYPE(alg->parameter, &der)) >= 0) {
+        const char *k = OSSL_PKEY_PARAM_ALGORITHM_ID_PARAMS;
+        OSSL_PARAM params[2];
+
+        /*
+         * Passing the same data with both the old (deprecated) and the
+         * new AlgID parameters OSSL_PARAM key.
+         */
+        params[0] = OSSL_PARAM_construct_octet_string(k, der, (size_t)derl);
+        params[1] = OSSL_PARAM_construct_end();
+        ret = EVP_PKEY_CTX_set_params(ctx, params);
+    }
+    OPENSSL_free(der);
+    return ret;
+}
+
+int EVP_PKEY_CTX_get_algor_params(EVP_PKEY_CTX *ctx, X509_ALGOR *alg)
+{
+    int ret = -1;                /* Assume the worst */
+    OSSL_PARAM params[2];
+    unsigned char *der = NULL;
+    size_t derl;
+    ASN1_TYPE *type = NULL;
+    const char *k = OSSL_PKEY_PARAM_ALGORITHM_ID_PARAMS;
+
+    /*
+     * We make two passes, the first to get the appropriate buffer size,
+     * and the second to get the actual value.
+     * Also, using both the old (deprecated) and the new AlgID parameters
+     * OSSL_PARAM key, and using whichever the provider responds to.
+     * Should the provider respond on both, the new key takes priority.
+     */
+    params[0] = OSSL_PARAM_construct_octet_string(k, NULL, 0);
+    params[1] = OSSL_PARAM_construct_end();
+
+    if (!EVP_PKEY_CTX_get_params(ctx, params))
+        goto err;
+
+    /*
+     * If alg->parameter is non-NULL, it will be changed by d2i_ASN1_TYPE()
+     * below.  If it is NULL, the d2i_ASN1_TYPE() call will allocate new
+     * space for it.  Either way, alg->parameter can be safely assigned
+     * with type after the d2i_ASN1_TYPE() call, with the safety that it
+     * will be ok.
+     */
+    type = alg->parameter;
+
+    derl = params[0].return_size;
+    if (OSSL_PARAM_modified(&params[0])
+        /* ... but, we should get a return size too! */
+        && derl != 0
+        && (der = OPENSSL_malloc(derl)) != NULL) {
+        unsigned char *derp = der;
+
+        params[0] = OSSL_PARAM_construct_octet_string(k, der, derl);
+        if (EVP_PKEY_CTX_get_params(ctx, params)
+            && OSSL_PARAM_modified(&params[0])
+            && d2i_ASN1_TYPE(&type, (const unsigned char **)&derp,
+                             derl) != NULL) {
+            /*
+             * Don't free alg->parameter, see comment further up.
+             * Worst case, alg->parameter gets assigned its own value.
+             */
+            alg->parameter = type;
+            ret = 1;
+        }
+    }
+ err:
+    OPENSSL_free(der);
+    return ret;
+}
+
+int EVP_PKEY_CTX_get_algor(EVP_PKEY_CTX *ctx, X509_ALGOR **alg)
+{
+    int ret = -1;                /* Assume the worst */
+    OSSL_PARAM params[2];
+    size_t aid_len = 0;
+    const char *k_aid = OSSL_SIGNATURE_PARAM_ALGORITHM_ID;
+
+    params[0] = OSSL_PARAM_construct_octet_string(k_aid, NULL, 0);
+    params[1] = OSSL_PARAM_construct_end();
+
+    if (EVP_PKEY_CTX_get_params(ctx, params) <= 0)
+        goto err;
+
+    if (OSSL_PARAM_modified(&params[0]))
+        aid_len = params[0].return_size;
+    if (aid_len == 0) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_GETTING_ALGORITHMIDENTIFIER_NOT_SUPPORTED);
+        ret = -2;
+        goto err;
+    }
+    if (alg != NULL) {
+        unsigned char *aid = NULL;
+        const unsigned char *pp = NULL;
+
+        if ((aid = OPENSSL_malloc(aid_len)) != NULL) {
+            params[0] = OSSL_PARAM_construct_octet_string(k_aid, aid, aid_len);
+            pp = aid;
+            if (EVP_PKEY_CTX_get_params(ctx, params)
+                && OSSL_PARAM_modified(&params[0])
+                && d2i_X509_ALGOR(alg, &pp, aid_len) != NULL)
+                ret = 1;
+        }
+        OPENSSL_free(aid);
+    }
+ err:
+    return ret;
+}
+
 #endif /* !defined(FIPS_MODULE) */

+ 45 - 1
libs/openssl/crypto/evp/evp_local.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2025 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
@@ -52,6 +52,7 @@ struct evp_cipher_ctx_st {
     int final_used;
     int block_mask;
     unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
+    size_t numpipes;
 
     /*
      * Opaque ctx returned from a providers cipher algorithm implementation
@@ -113,6 +114,8 @@ struct evp_keymgmt_st {
     /* Generation, a complex constructor */
     OSSL_FUNC_keymgmt_gen_init_fn *gen_init;
     OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template;
+    OSSL_FUNC_keymgmt_gen_get_params_fn *gen_get_params;
+    OSSL_FUNC_keymgmt_gen_gettable_params_fn *gen_gettable_params;
     OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params;
     OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params;
     OSSL_FUNC_keymgmt_gen_fn *gen;
@@ -165,8 +168,14 @@ struct evp_signature_st {
     OSSL_FUNC_signature_newctx_fn *newctx;
     OSSL_FUNC_signature_sign_init_fn *sign_init;
     OSSL_FUNC_signature_sign_fn *sign;
+    OSSL_FUNC_signature_sign_message_init_fn *sign_message_init;
+    OSSL_FUNC_signature_sign_message_update_fn *sign_message_update;
+    OSSL_FUNC_signature_sign_message_final_fn *sign_message_final;
     OSSL_FUNC_signature_verify_init_fn *verify_init;
     OSSL_FUNC_signature_verify_fn *verify;
+    OSSL_FUNC_signature_verify_message_init_fn *verify_message_init;
+    OSSL_FUNC_signature_verify_message_update_fn *verify_message_update;
+    OSSL_FUNC_signature_verify_message_final_fn *verify_message_final;
     OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init;
     OSSL_FUNC_signature_verify_recover_fn *verify_recover;
     OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init;
@@ -187,8 +196,34 @@ struct evp_signature_st {
     OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params;
     OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params;
     OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params;
+
+    /* Signature object checking */
+    OSSL_FUNC_signature_query_key_types_fn *query_key_types;
 } /* EVP_SIGNATURE */;
 
+struct evp_skeymgmt_st {
+    int name_id;
+    char *type_name;
+    const char *description;
+    OSSL_PROVIDER *prov;
+    CRYPTO_REF_COUNT refcnt;
+
+    /* Import and export routines */
+    OSSL_FUNC_skeymgmt_imp_settable_params_fn *imp_params;
+    OSSL_FUNC_skeymgmt_import_fn *import;
+    OSSL_FUNC_skeymgmt_export_fn *export;
+
+    /* Key generation */
+    OSSL_FUNC_skeymgmt_gen_settable_params_fn *gen_params;
+    OSSL_FUNC_skeymgmt_generate_fn *generate;
+
+    /* Key identifier */
+    OSSL_FUNC_skeymgmt_get_key_id_fn *get_key_id;
+
+    /* destructor */
+    OSSL_FUNC_skeymgmt_free_fn *free;
+} /* EVP_SKEYMGMT */;
+
 struct evp_asym_cipher_st {
     int name_id;
     char *type_name;
@@ -305,6 +340,15 @@ EVP_KEYEXCH *evp_keyexch_fetch_from_prov(OSSL_PROVIDER *prov,
 EVP_KEM *evp_kem_fetch_from_prov(OSSL_PROVIDER *prov,
                                  const char *name,
                                  const char *properties);
+EVP_CIPHER *evp_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
+                                       const char *algorithm,
+                                       const char *properties);
+EVP_MD *evp_digest_fetch_from_prov(OSSL_PROVIDER *prov,
+                                   const char *algorithm,
+                                   const char *properties);
+EVP_MAC *evp_mac_fetch_from_prov(OSSL_PROVIDER *prov,
+                                 const char *algorithm,
+                                 const char *properties);
 
 /* Internal structure constructors for fetched methods */
 EVP_MD *evp_md_new(void);

+ 29 - 21
libs/openssl/crypto/evp/exchange.c

@@ -18,6 +18,16 @@
 #include "crypto/evp.h"
 #include "evp_local.h"
 
+static void evp_keyexch_free(void *data)
+{
+    EVP_KEYEXCH_free(data);
+}
+
+static int evp_keyexch_up_ref(void *data)
+{
+    return EVP_KEYEXCH_up_ref(data);
+}
+
 static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
 {
     EVP_KEYEXCH *exchange = OPENSSL_zalloc(sizeof(EVP_KEYEXCH));
@@ -25,12 +35,13 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
     if (exchange == NULL)
         return NULL;
 
-    if (!CRYPTO_NEW_REF(&exchange->refcnt, 1)) {
+    if (!CRYPTO_NEW_REF(&exchange->refcnt, 1)
+        || !ossl_provider_up_ref(prov)) {
+        CRYPTO_FREE_REF(&exchange->refcnt);
         OPENSSL_free(exchange);
         return NULL;
     }
     exchange->prov = prov;
-    ossl_provider_up_ref(prov);
 
     return exchange;
 }
@@ -172,8 +183,8 @@ EVP_KEYEXCH *EVP_KEYEXCH_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
 {
     return evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties,
                              evp_keyexch_from_algorithm,
-                             (int (*)(void *))EVP_KEYEXCH_up_ref,
-                             (void (*)(void *))EVP_KEYEXCH_free);
+                             evp_keyexch_up_ref,
+                             evp_keyexch_free);
 }
 
 EVP_KEYEXCH *evp_keyexch_fetch_from_prov(OSSL_PROVIDER *prov,
@@ -183,8 +194,8 @@ EVP_KEYEXCH *evp_keyexch_fetch_from_prov(OSSL_PROVIDER *prov,
     return evp_generic_fetch_from_prov(prov, OSSL_OP_KEYEXCH,
                                        algorithm, properties,
                                        evp_keyexch_from_algorithm,
-                                       (int (*)(void *))EVP_KEYEXCH_up_ref,
-                                       (void (*)(void *))EVP_KEYEXCH_free);
+                                       evp_keyexch_up_ref,
+                                       evp_keyexch_free);
 }
 
 int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
@@ -434,10 +445,7 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer,
     ret = ctx->op.kex.exchange->set_peer(ctx->op.kex.algctx, provkey);
     if (ret <= 0)
         return ret;
-    EVP_PKEY_free(ctx->peerkey);
-    ctx->peerkey = peer;
-    EVP_PKEY_up_ref(peer);
-    return 1;
+    goto common;
 
  legacy:
 #ifdef FIPS_MODULE
@@ -489,19 +497,19 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer,
         return -1;
     }
 
-    EVP_PKEY_free(ctx->peerkey);
-    ctx->peerkey = peer;
-
     ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
-
-    if (ret <= 0) {
-        ctx->peerkey = NULL;
+    if (ret <= 0)
         return ret;
-    }
+#endif
+
+ common:
+    if (!EVP_PKEY_up_ref(peer))
+        return -1;
+
+    EVP_PKEY_free(ctx->peerkey);
+    ctx->peerkey = peer;
 
-    EVP_PKEY_up_ref(peer);
     return 1;
-#endif
 }
 
 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
@@ -568,8 +576,8 @@ void EVP_KEYEXCH_do_all_provided(OSSL_LIB_CTX *libctx,
     evp_generic_do_all(libctx, OSSL_OP_KEYEXCH,
                        (void (*)(void *, void *))fn, arg,
                        evp_keyexch_from_algorithm,
-                       (int (*)(void *))EVP_KEYEXCH_up_ref,
-                       (void (*)(void *))EVP_KEYEXCH_free);
+                       evp_keyexch_up_ref,
+                       evp_keyexch_free);
 }
 
 int EVP_KEYEXCH_names_do_all(const EVP_KEYEXCH *keyexch,

+ 12 - 9
libs/openssl/crypto/evp/kdf_meth.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -68,10 +68,9 @@ static void *evp_kdf_from_algorithm(int name_id,
         return NULL;
     }
     kdf->name_id = name_id;
-    if ((kdf->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
-        evp_kdf_free(kdf);
-        return NULL;
-    }
+    if ((kdf->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
+        goto err;
+
     kdf->description = algodef->algorithm_description;
 
     for (; fns->function_id != 0; fns++) {
@@ -145,15 +144,19 @@ static void *evp_kdf_from_algorithm(int name_id,
          * a derive function, and a complete set of context management
          * functions.
          */
-        evp_kdf_free(kdf);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
+        goto err;
     }
+    if (prov != NULL && !ossl_provider_up_ref(prov))
+        goto err;
+
     kdf->prov = prov;
-    if (prov != NULL)
-        ossl_provider_up_ref(prov);
 
     return kdf;
+
+err:
+    evp_kdf_free(kdf);
+    return NULL;
 }
 
 EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,

+ 20 - 9
libs/openssl/crypto/evp/kem.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2025 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
@@ -17,6 +17,16 @@
 #include "crypto/evp.h"
 #include "evp_local.h"
 
+static void evp_kem_free(void *data)
+{
+    EVP_KEM_free(data);
+}
+
+static int evp_kem_up_ref(void *data)
+{
+    return EVP_KEM_up_ref(data);
+}
+
 static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation,
                         const OSSL_PARAM params[], EVP_PKEY *authkey)
 {
@@ -278,12 +288,13 @@ static EVP_KEM *evp_kem_new(OSSL_PROVIDER *prov)
     if (kem == NULL)
         return NULL;
 
-    if (!CRYPTO_NEW_REF(&kem->refcnt, 1)) {
+    if (!CRYPTO_NEW_REF(&kem->refcnt, 1)
+        || !ossl_provider_up_ref(prov)) {
+        CRYPTO_FREE_REF(&kem->refcnt);
         OPENSSL_free(kem);
         return NULL;
     }
     kem->prov = prov;
-    ossl_provider_up_ref(prov);
 
     return kem;
 }
@@ -452,8 +463,8 @@ EVP_KEM *EVP_KEM_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
 {
     return evp_generic_fetch(ctx, OSSL_OP_KEM, algorithm, properties,
                              evp_kem_from_algorithm,
-                             (int (*)(void *))EVP_KEM_up_ref,
-                             (void (*)(void *))EVP_KEM_free);
+                             evp_kem_up_ref,
+                             evp_kem_free);
 }
 
 EVP_KEM *evp_kem_fetch_from_prov(OSSL_PROVIDER *prov, const char *algorithm,
@@ -461,8 +472,8 @@ EVP_KEM *evp_kem_fetch_from_prov(OSSL_PROVIDER *prov, const char *algorithm,
 {
     return evp_generic_fetch_from_prov(prov, OSSL_OP_KEM, algorithm, properties,
                                        evp_kem_from_algorithm,
-                                       (int (*)(void *))EVP_KEM_up_ref,
-                                       (void (*)(void *))EVP_KEM_free);
+                                       evp_kem_up_ref,
+                                       evp_kem_free);
 }
 
 int EVP_KEM_is_a(const EVP_KEM *kem, const char *name)
@@ -491,8 +502,8 @@ void EVP_KEM_do_all_provided(OSSL_LIB_CTX *libctx,
 {
     evp_generic_do_all(libctx, OSSL_OP_KEM, (void (*)(void *, void *))fn, arg,
                        evp_kem_from_algorithm,
-                       (int (*)(void *))EVP_KEM_up_ref,
-                       (void (*)(void *))EVP_KEM_free);
+                       evp_kem_up_ref,
+                       evp_kem_free);
 }
 
 int EVP_KEM_names_do_all(const EVP_KEM *kem,

+ 65 - 9
libs/openssl/crypto/evp/keymgmt_meth.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -17,6 +17,16 @@
 #include "crypto/evp.h"
 #include "evp_local.h"
 
+static void evp_keymgmt_free(void *data)
+{
+    EVP_KEYMGMT_free(data);
+}
+
+static int evp_keymgmt_up_ref(void *data)
+{
+    return EVP_KEYMGMT_up_ref(data);
+}
+
 static void *keymgmt_new(void)
 {
     EVP_KEYMGMT *keymgmt = NULL;
@@ -60,6 +70,7 @@ static void *keymgmt_from_algorithm(int name_id,
     int setgenparamfncnt = 0;
     int importfncnt = 0, exportfncnt = 0;
     int importtypesfncnt = 0, exporttypesfncnt = 0;
+    int getgenparamfncnt = 0;
 
     if ((keymgmt = keymgmt_new()) == NULL)
         return NULL;
@@ -100,6 +111,20 @@ static void *keymgmt_from_algorithm(int name_id,
                     OSSL_FUNC_keymgmt_gen_settable_params(fns);
             }
             break;
+        case OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS:
+            if (keymgmt->gen_get_params == NULL) {
+                getgenparamfncnt++;
+                keymgmt->gen_get_params =
+                    OSSL_FUNC_keymgmt_gen_get_params(fns);
+            }
+            break;
+        case OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS:
+            if (keymgmt->gen_gettable_params == NULL) {
+                getgenparamfncnt++;
+                keymgmt->gen_gettable_params =
+                    OSSL_FUNC_keymgmt_gen_gettable_params(fns);
+            }
+            break;
         case OSSL_FUNC_KEYMGMT_GEN:
             if (keymgmt->gen == NULL)
                 keymgmt->gen = OSSL_FUNC_keymgmt_gen(fns);
@@ -225,6 +250,7 @@ static void *keymgmt_from_algorithm(int name_id,
         || (getparamfncnt != 0 && getparamfncnt != 2)
         || (setparamfncnt != 0 && setparamfncnt != 2)
         || (setgenparamfncnt != 0 && setgenparamfncnt != 2)
+        || (getgenparamfncnt != 0 && getgenparamfncnt != 2)
         || (importfncnt != 0 && importfncnt != 2)
         || (exportfncnt != 0 && exportfncnt != 2)
         || (keymgmt->gen != NULL
@@ -252,8 +278,8 @@ EVP_KEYMGMT *evp_keymgmt_fetch_from_prov(OSSL_PROVIDER *prov,
     return evp_generic_fetch_from_prov(prov, OSSL_OP_KEYMGMT,
                                        name, properties,
                                        keymgmt_from_algorithm,
-                                       (int (*)(void *))EVP_KEYMGMT_up_ref,
-                                       (void (*)(void *))EVP_KEYMGMT_free);
+                                       evp_keymgmt_up_ref,
+                                       evp_keymgmt_free);
 }
 
 EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
@@ -261,8 +287,8 @@ EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
 {
     return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties,
                              keymgmt_from_algorithm,
-                             (int (*)(void *))EVP_KEYMGMT_up_ref,
-                             (void (*)(void *))EVP_KEYMGMT_free);
+                             evp_keymgmt_up_ref,
+                             evp_keymgmt_free);
 }
 
 int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt)
@@ -327,8 +353,8 @@ void EVP_KEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx,
     evp_generic_do_all(libctx, OSSL_OP_KEYMGMT,
                        (void (*)(void *, void *))fn, arg,
                        keymgmt_from_algorithm,
-                       (int (*)(void *))EVP_KEYMGMT_up_ref,
-                       (void (*)(void *))EVP_KEYMGMT_free);
+                       evp_keymgmt_up_ref,
+                       evp_keymgmt_free);
 }
 
 int EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt,
@@ -405,12 +431,42 @@ const OSSL_PARAM *EVP_KEYMGMT_gen_settable_params(const EVP_KEYMGMT *keymgmt)
     return keymgmt->gen_settable_params(NULL, provctx);
 }
 
+int evp_keymgmt_gen_get_params(const EVP_KEYMGMT *keymgmt, void *genctx,
+                               OSSL_PARAM params[])
+{
+    if (keymgmt->gen_get_params == NULL)
+        return 0;
+    return keymgmt->gen_get_params(genctx, params);
+}
+
+const OSSL_PARAM *EVP_KEYMGMT_gen_gettable_params(const EVP_KEYMGMT *keymgmt)
+{
+    void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt));
+
+    if (keymgmt->gen_gettable_params == NULL)
+        return NULL;
+    return keymgmt->gen_gettable_params(NULL, provctx);
+}
+
 void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
                       OSSL_CALLBACK *cb, void *cbarg)
 {
-    if (keymgmt->gen == NULL)
+    void *ret;
+    const char *desc = keymgmt->description != NULL ? keymgmt->description : "";
+
+    if (keymgmt->gen == NULL) {
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED,
+                       "%s key generation:%s", keymgmt->type_name, desc);
         return NULL;
-    return keymgmt->gen(genctx, cb, cbarg);
+    }
+
+    ERR_set_mark();
+    ret = keymgmt->gen(genctx, cb, cbarg);
+    if (ret == NULL && ERR_count_to_mark() == 0)
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_FAILURE,
+                       "%s key generation:%s", keymgmt->type_name, desc);
+    ERR_clear_last_mark();
+    return ret;
 }
 
 void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx)

+ 113 - 41
libs/openssl/crypto/evp/m_sigver.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2025 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
@@ -16,8 +16,6 @@
 #include "internal/numbers.h"   /* includes SIZE_MAX */
 #include "evp_local.h"
 
-#ifndef FIPS_MODULE
-
 static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
 {
     ERR_raise(ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED);
@@ -44,6 +42,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
 {
     EVP_PKEY_CTX *locpctx = NULL;
     EVP_SIGNATURE *signature = NULL;
+    const char *desc;
     EVP_KEYMGMT *tmp_keymgmt = NULL;
     const OSSL_PROVIDER *tmp_prov = NULL;
     const char *supported_sig = NULL;
@@ -253,16 +252,19 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
         }
     }
 
+    desc = signature->description != NULL ? signature->description : "";
     if (ver) {
         if (signature->digest_verify_init == NULL) {
-            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+            ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+                           "%s digest_verify_init:%s", signature->type_name, desc);
             goto err;
         }
         ret = signature->digest_verify_init(locpctx->op.sig.algctx,
                                             mdname, provkey, params);
     } else {
         if (signature->digest_sign_init == NULL) {
-            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+            ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+                           "%s digest_sign_init:%s", signature->type_name, desc);
             goto err;
         }
         ret = signature->digest_sign_init(locpctx->op.sig.algctx,
@@ -277,6 +279,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
         goto end;
     if (type == NULL)   /* This check is redundant but clarifies matters */
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST);
+    ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+                   ver ? "%s digest_verify_init:%s" : "%s digest_sign_init:%s",
+                   signature->type_name, desc);
 
  err:
     evp_pkey_ctx_free_old_ops(locpctx);
@@ -355,12 +360,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
         ctx->pctx->flag_call_digest_custom = 1;
 
     ret = 1;
-
  end:
-#ifndef FIPS_MODULE
     if (ret > 0)
         ret = evp_pkey_ctx_use_cached_data(locpctx);
-#endif
 
     EVP_KEYMGMT_free(tmp_keymgmt);
     return ret > 0 ? 1 : 0;
@@ -397,11 +399,13 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
     return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1,
                           NULL);
 }
-#endif /* FIPS_MDOE */
 
 int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
 {
+    EVP_SIGNATURE *signature;
+    const char *desc;
     EVP_PKEY_CTX *pctx = ctx->pctx;
+    int ret;
 
     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
         ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
@@ -414,13 +418,21 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
             || pctx->op.sig.signature == NULL)
         goto legacy;
 
-    if (pctx->op.sig.signature->digest_sign_update == NULL) {
-        ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    signature = pctx->op.sig.signature;
+    desc = signature->description != NULL ? signature->description : "";
+    if (signature->digest_sign_update == NULL) {
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+                       "%s digest_sign_update:%s", signature->type_name, desc);
         return 0;
     }
 
-    return pctx->op.sig.signature->digest_sign_update(pctx->op.sig.algctx,
-                                                      data, dsize);
+    ERR_set_mark();
+    ret = signature->digest_sign_update(pctx->op.sig.algctx, data, dsize);
+    if (ret <= 0 && ERR_count_to_mark() == 0)
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+                       "%s digest_sign_update:%s", signature->type_name, desc);
+    ERR_clear_last_mark();
+    return ret;
 
  legacy:
     if (pctx != NULL) {
@@ -436,7 +448,10 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
 
 int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
 {
+    EVP_SIGNATURE *signature;
+    const char *desc;
     EVP_PKEY_CTX *pctx = ctx->pctx;
+    int ret;
 
     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
         ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
@@ -449,13 +464,21 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
             || pctx->op.sig.signature == NULL)
         goto legacy;
 
-    if (pctx->op.sig.signature->digest_verify_update == NULL) {
-        ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    signature = pctx->op.sig.signature;
+    desc = signature->description != NULL ? signature->description : "";
+    if (signature->digest_verify_update == NULL) {
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+                       "%s digest_verify_update:%s", signature->type_name, desc);
         return 0;
     }
 
-    return pctx->op.sig.signature->digest_verify_update(pctx->op.sig.algctx,
-                                                        data, dsize);
+    ERR_set_mark();
+    ret = signature->digest_verify_update(pctx->op.sig.algctx, data, dsize);
+    if (ret <= 0 && ERR_count_to_mark() == 0)
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+                       "%s digest_verify_update:%s", signature->type_name, desc);
+    ERR_clear_last_mark();
+    return ret;
 
  legacy:
     if (pctx != NULL) {
@@ -469,11 +492,13 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
     return EVP_DigestUpdate(ctx, data, dsize);
 }
 
-#ifndef FIPS_MODULE
 int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
                         size_t *siglen)
 {
-    int sctx = 0, r = 0;
+    EVP_SIGNATURE *signature;
+    const char *desc;
+    int sctx = 0;
+    int r = 0;
     EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
 
     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
@@ -487,15 +512,28 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
             || pctx->op.sig.signature == NULL)
         goto legacy;
 
+    signature = pctx->op.sig.signature;
+    desc = signature->description != NULL ? signature->description : "";
+    if (signature->digest_sign_final == NULL) {
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+                       "%s digest_sign_final:%s", signature->type_name, desc);
+        return 0;
+    }
+
     if (sigret != NULL && (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) {
         /* try dup */
         dctx = EVP_PKEY_CTX_dup(pctx);
         if (dctx != NULL)
             pctx = dctx;
     }
-    r = pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
-                                                  sigret, siglen,
-                                                  sigret == NULL ? 0 : *siglen);
+
+    ERR_set_mark();
+    r = signature->digest_sign_final(pctx->op.sig.algctx, sigret, siglen,
+                                     sigret == NULL ? 0 : *siglen);
+    if (!r && ERR_count_to_mark() == 0)
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+                       "%s digest_sign_final:%s", signature->type_name, desc);
+    ERR_clear_last_mark();
     if (dctx == NULL && sigret != NULL)
         ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
     else
@@ -569,7 +607,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
         } else {
             int s = EVP_MD_get_size(ctx->digest);
 
-            if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
+            if (s <= 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
                 return 0;
         }
     }
@@ -580,28 +618,41 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
                    const unsigned char *tbs, size_t tbslen)
 {
     EVP_PKEY_CTX *pctx = ctx->pctx;
+    int ret;
+
+    if (pctx == NULL) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+        return 0;
+    }
 
     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
         ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
         return 0;
     }
 
-    if (pctx != NULL
-            && pctx->operation == EVP_PKEY_OP_SIGNCTX
+    if (pctx->operation == EVP_PKEY_OP_SIGNCTX
             && pctx->op.sig.algctx != NULL
             && pctx->op.sig.signature != NULL) {
-        if (pctx->op.sig.signature->digest_sign != NULL) {
+        EVP_SIGNATURE *signature = pctx->op.sig.signature;
+
+        if (signature->digest_sign != NULL) {
+            const char *desc = signature->description != NULL ? signature->description : "";
+
             if (sigret != NULL)
                 ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
-            return pctx->op.sig.signature->digest_sign(pctx->op.sig.algctx,
-                                                       sigret, siglen,
-                                                       sigret == NULL ? 0 : *siglen,
-                                                       tbs, tbslen);
+            ERR_set_mark();
+            ret = signature->digest_sign(pctx->op.sig.algctx, sigret, siglen,
+                                         sigret == NULL ? 0 : *siglen, tbs, tbslen);
+            if (ret <= 0 && ERR_count_to_mark() == 0)
+                ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+                               "%s digest_sign:%s", signature->type_name, desc);
+            ERR_clear_last_mark();
+            return ret;
         }
     } else {
         /* legacy */
-        if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL)
-            return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
+        if (pctx->pmeth != NULL && pctx->pmeth->digestsign != NULL)
+            return pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
     }
 
     if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
@@ -612,10 +663,12 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
 int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
                           size_t siglen)
 {
+    EVP_SIGNATURE *signature;
+    const char *desc;
+    int vctx = 0;
+    unsigned int mdlen = 0;
     unsigned char md[EVP_MAX_MD_SIZE];
     int r = 0;
-    unsigned int mdlen = 0;
-    int vctx = 0;
     EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
 
     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
@@ -629,14 +682,27 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
             || pctx->op.sig.signature == NULL)
         goto legacy;
 
+    signature = pctx->op.sig.signature;
+    desc = signature->description != NULL ? signature->description : "";
+    if (signature->digest_verify_final == NULL) {
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+                       "%s digest_verify_final:%s", signature->type_name, desc);
+        return 0;
+    }
+
     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) {
         /* try dup */
         dctx = EVP_PKEY_CTX_dup(pctx);
         if (dctx != NULL)
             pctx = dctx;
     }
-    r = pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
-                                                    sig, siglen);
+
+    ERR_set_mark();
+    r = signature->digest_verify_final(pctx->op.sig.algctx, sig, siglen);
+    if (!r && ERR_count_to_mark() == 0)
+        ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+                       "%s digest_verify_final:%s", signature->type_name, desc);
+    ERR_clear_last_mark();
     if (dctx == NULL)
         ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
     else
@@ -704,19 +770,25 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
             && pctx->op.sig.algctx != NULL
             && pctx->op.sig.signature != NULL) {
         if (pctx->op.sig.signature->digest_verify != NULL) {
+            EVP_SIGNATURE *signature = pctx->op.sig.signature;
+            const char *desc = signature->description != NULL ? signature->description : "";
+            int ret;
+
             ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
-            return pctx->op.sig.signature->digest_verify(pctx->op.sig.algctx,
-                                                         sigret, siglen,
-                                                         tbs, tbslen);
+            ERR_set_mark();
+            ret = signature->digest_verify(pctx->op.sig.algctx, sigret, siglen, tbs, tbslen);
+            if (ret <= 0 && ERR_count_to_mark() == 0)
+                ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+                               "%s digest_verify:%s", signature->type_name, desc);
+            ERR_clear_last_mark();
+            return ret;
         }
     } else {
         /* legacy */
         if (pctx->pmeth != NULL && pctx->pmeth->digestverify != NULL)
             return pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
     }
-
     if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
         return -1;
     return EVP_DigestVerifyFinal(ctx, sigret, siglen);
 }
-#endif /* FIPS_MODULE */

+ 16 - 1
libs/openssl/crypto/evp/mac_lib.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2025 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
@@ -115,9 +115,24 @@ size_t EVP_MAC_CTX_get_block_size(EVP_MAC_CTX *ctx)
 int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen,
                  const OSSL_PARAM params[])
 {
+    if (ctx->meth->init == NULL) {
+        ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED);
+        return 0;
+    }
     return ctx->meth->init(ctx->algctx, key, keylen, params);
 }
 
+int EVP_MAC_init_SKEY(EVP_MAC_CTX *ctx, EVP_SKEY *skey, const OSSL_PARAM params[])
+{
+    if (ctx->meth->init_skey == NULL
+        || skey->skeymgmt->prov != ctx->meth->prov
+        || ctx->meth->init_skey == NULL) {
+        ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED);
+        return 0;
+    }
+    return ctx->meth->init_skey(ctx->algctx, skey->keydata, params);
+}
+
 int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen)
 {
     return ctx->meth->update(ctx->algctx, data, datalen);

+ 35 - 12
libs/openssl/crypto/evp/mac_meth.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -60,17 +60,17 @@ static void *evp_mac_from_algorithm(int name_id,
 {
     const OSSL_DISPATCH *fns = algodef->implementation;
     EVP_MAC *mac = NULL;
-    int fnmaccnt = 0, fnctxcnt = 0;
+    int fnmaccnt = 0, fnctxcnt = 0, mac_init_found = 0;
 
     if ((mac = evp_mac_new()) == NULL) {
         ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
-        return NULL;
+        goto err;
     }
     mac->name_id = name_id;
-    if ((mac->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
-        evp_mac_free(mac);
-        return NULL;
-    }
+
+    if ((mac->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
+        goto err;
+
     mac->description = algodef->algorithm_description;
 
     for (; fns->function_id != 0; fns++) {
@@ -96,7 +96,7 @@ static void *evp_mac_from_algorithm(int name_id,
             if (mac->init != NULL)
                 break;
             mac->init = OSSL_FUNC_mac_init(fns);
-            fnmaccnt++;
+            mac_init_found = 1;
             break;
         case OSSL_FUNC_MAC_UPDATE:
             if (mac->update != NULL)
@@ -143,8 +143,15 @@ static void *evp_mac_from_algorithm(int name_id,
                 break;
             mac->set_ctx_params = OSSL_FUNC_mac_set_ctx_params(fns);
             break;
+        case OSSL_FUNC_MAC_INIT_SKEY:
+            if (mac->init_skey != NULL)
+                break;
+            mac->init_skey = OSSL_FUNC_mac_init_skey(fns);
+            mac_init_found = 1;
+            break;
         }
     }
+    fnmaccnt += mac_init_found;
     if (fnmaccnt != 3
         || fnctxcnt != 2) {
         /*
@@ -152,15 +159,20 @@ static void *evp_mac_from_algorithm(int name_id,
          * a complete set of "mac" functions, and a complete set of context
          * management functions, as well as the size function.
          */
-        evp_mac_free(mac);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
+        goto err;
     }
+
+    if (prov != NULL && !ossl_provider_up_ref(prov))
+        goto err;
+
     mac->prov = prov;
-    if (prov != NULL)
-        ossl_provider_up_ref(prov);
 
     return mac;
+
+err:
+    evp_mac_free(mac);
+    return NULL;
 }
 
 EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
@@ -241,3 +253,14 @@ void EVP_MAC_do_all_provided(OSSL_LIB_CTX *libctx,
                        (void (*)(void *, void *))fn, arg,
                        evp_mac_from_algorithm, evp_mac_up_ref, evp_mac_free);
 }
+
+EVP_MAC *evp_mac_fetch_from_prov(OSSL_PROVIDER *prov,
+                                 const char *algorithm,
+                                 const char *properties)
+{
+    return evp_generic_fetch_from_prov(prov, OSSL_OP_MAC,
+                                       algorithm, properties,
+                                       evp_mac_from_algorithm,
+                                       evp_mac_up_ref,
+                                       evp_mac_free);
+}

+ 2 - 2
libs/openssl/crypto/evp/p5_crpt.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 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
@@ -78,7 +78,7 @@ int PKCS5_PBE_keyivgen_ex(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
         passlen = strlen(pass);
 
     mdsize = EVP_MD_get_size(md);
-    if (mdsize < 0)
+    if (mdsize <= 0)
         goto err;
 
     kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF1, propq);

+ 13 - 6
libs/openssl/crypto/evp/p_legacy.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -24,10 +24,16 @@
 
 int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
 {
-    int ret = EVP_PKEY_assign_RSA(pkey, key);
+    int ret;
+
+    if (!RSA_up_ref(key))
+        return 0;
+
+    ret = EVP_PKEY_assign_RSA(pkey, key);
+
+    if (!ret)
+        RSA_free(key);
 
-    if (ret)
-        RSA_up_ref(key);
     return ret;
 }
 
@@ -49,8 +55,9 @@ RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
 {
     RSA *ret = evp_pkey_get0_RSA_int(pkey);
 
-    if (ret != NULL)
-        RSA_up_ref(ret);
+    if (ret != NULL && !RSA_up_ref(ret))
+        ret = NULL;
+
     return ret;
 }
 

+ 89 - 32
libs/openssl/crypto/evp/p_lib.c

@@ -54,11 +54,10 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
                          int len, EVP_KEYMGMT *keymgmt);
 static void evp_pkey_free_it(EVP_PKEY *key);
 
-#ifndef FIPS_MODULE
-
 /* The type of parameters selected in key parameter functions */
 # define SELECT_PARAMETERS OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
 
+#ifndef FIPS_MODULE
 int EVP_PKEY_get_bits(const EVP_PKEY *pkey)
 {
     int size = 0;
@@ -123,6 +122,7 @@ void *EVP_PKEY_get_ex_data(const EVP_PKEY *key, int idx)
 {
     return CRYPTO_get_ex_data(&key->ex_data, idx);
 }
+#endif  /* !FIPS_MODULE */
 
 int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
 {
@@ -133,6 +133,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
     EVP_PKEY *downgraded_from = NULL;
     int ok = 0;
 
+#ifndef FIPS_MODULE
     /*
      * If |to| is a legacy key and |from| isn't, we must make a downgraded
      * copy of |from|.  If that fails, this function fails.
@@ -142,6 +143,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
             goto end;
         from = downgraded_from;
     }
+#endif  /* !FIPS_MODULE */
 
     /*
      * Make sure |to| is typed.  Content is less important at this early
@@ -156,19 +158,25 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
      * further down help us find out if they are the same or not.
      */
     if (evp_pkey_is_blank(to)) {
+#ifndef FIPS_MODULE
         if (evp_pkey_is_legacy(from)) {
             if (EVP_PKEY_set_type(to, from->type) == 0)
                 goto end;
-        } else {
+        } else
+#endif  /* !FIPS_MODULE */
+        {
             if (EVP_PKEY_set_type_by_keymgmt(to, from->keymgmt) == 0)
                 goto end;
         }
-    } else if (evp_pkey_is_legacy(to)) {
+    }
+#ifndef FIPS_MODULE
+    else if (evp_pkey_is_legacy(to)) {
         if (to->type != from->type) {
             ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
             goto end;
         }
     }
+#endif  /* !FIPS_MODULE */
 
     if (EVP_PKEY_missing_parameters(from)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_MISSING_PARAMETERS);
@@ -189,6 +197,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
         goto end;
     }
 
+#ifndef FIPS_MODULE
     /*
      * If |to| is provided, we know that |from| is legacy at this point.
      * Try exporting |from| to |to|'s keymgmt, then use evp_keymgmt_dup()
@@ -218,6 +227,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
     /* Both keys are legacy */
     if (from->ameth != NULL && from->ameth->param_copy != NULL)
         ok = from->ameth->param_copy(to, from);
+#endif  /* !FIPS_MODULE */
  end:
     EVP_PKEY_free(downgraded_from);
     return ok;
@@ -226,10 +236,14 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
 int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
 {
     if (pkey != NULL) {
+#ifdef FIPS_MODULE
+        return !evp_keymgmt_util_has((EVP_PKEY *)pkey, SELECT_PARAMETERS);
+#else
         if (pkey->keymgmt != NULL)
             return !evp_keymgmt_util_has((EVP_PKEY *)pkey, SELECT_PARAMETERS);
-        else if (pkey->ameth != NULL && pkey->ameth->param_missing != NULL)
+        if (pkey->ameth != NULL && pkey->ameth->param_missing != NULL)
             return pkey->ameth->param_missing(pkey);
+#endif  /* FIPS_MODULE */
     }
     return 0;
 }
@@ -242,6 +256,9 @@ int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
 static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b,
                             int selection)
 {
+#ifdef FIPS_MODULE
+    return evp_keymgmt_util_match((EVP_PKEY *)a, (EVP_PKEY *)b, selection);
+#else
     EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL;
     void *keydata1 = NULL, *keydata2 = NULL, *tmp_keydata = NULL;
 
@@ -300,17 +317,23 @@ static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b,
         return -2;
 
     return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
+#endif  /* FIPS_MODULE */
 }
 
+#ifndef FIPS_MODULE
 # ifndef OPENSSL_NO_DEPRECATED_3_0
 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
 {
     return EVP_PKEY_parameters_eq(a, b);
 }
-#endif
+# endif
+#endif  /* FIPS_MODULE */
 
 int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b)
 {
+#ifdef FIPS_MODULE
+    return evp_pkey_cmp_any(a, b, SELECT_PARAMETERS);
+#else
     /*
      * This will just call evp_keymgmt_util_match when legacy support
      * is gone.
@@ -325,14 +348,17 @@ int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b)
     if (a->ameth != NULL && a->ameth->param_cmp != NULL)
         return a->ameth->param_cmp(a, b);
     return -2;
+#endif  /* !FIPS_MODULE */
 }
 
+#ifndef FIPS_MODULE
 # ifndef OPENSSL_NO_DEPRECATED_3_0
 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
 {
     return EVP_PKEY_eq(a, b);
 }
-#endif
+# endif
+#endif  /* !FIPS_MODULE */
 
 int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b)
 {
@@ -347,7 +373,10 @@ int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b)
     if (a == NULL || b == NULL)
         return 0;
 
-    if (a->keymgmt != NULL || b->keymgmt != NULL) {
+#ifndef FIPS_MODULE
+    if (a->keymgmt != NULL || b->keymgmt != NULL)
+#endif  /* !FIPS_MODULE */
+    {
         int selection = SELECT_PARAMETERS;
 
         if (evp_keymgmt_util_has((EVP_PKEY *)a, OSSL_KEYMGMT_SELECT_PUBLIC_KEY)
@@ -358,6 +387,7 @@ int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b)
         return evp_pkey_cmp_any(a, b, selection);
     }
 
+#ifndef FIPS_MODULE
     /* All legacy keys */
     if (a->type != b->type)
         return -1;
@@ -376,9 +406,10 @@ int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b)
     }
 
     return -2;
+#endif  /* !FIPS_MODULE */
 }
 
-
+#ifndef FIPS_MODULE
 static EVP_PKEY *new_raw_key_int(OSSL_LIB_CTX *libctx,
                                  const char *strtype,
                                  const char *propq,
@@ -525,8 +556,7 @@ EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
     return new_raw_key_int(NULL, NULL, NULL, type, e, pub, len, 0);
 }
 
-struct raw_key_details_st
-{
+struct raw_key_details_st {
     unsigned char **key;
     size_t *len;
     int selection;
@@ -867,17 +897,25 @@ const DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
 
 int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
 {
-    int ret = EVP_PKEY_assign_DSA(pkey, key);
-    if (ret)
-        DSA_up_ref(key);
+    int ret;
+
+    if (!DSA_up_ref(key))
+        return 0;
+
+    ret = EVP_PKEY_assign_DSA(pkey, key);
+
+    if (!ret)
+        DSA_free(key);
+
     return ret;
 }
 DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
 {
     DSA *ret = evp_pkey_get0_DSA_int(pkey);
 
-    if (ret != NULL)
-        DSA_up_ref(ret);
+    if (ret != NULL && !DSA_up_ref(ret))
+        return NULL;
+
     return ret;
 }
 # endif /*  OPENSSL_NO_DSA */
@@ -943,10 +981,14 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *dhkey)
     else
         type = DH_get0_q(dhkey) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX;
 
+    if (!DH_up_ref(dhkey))
+        return 0;
+
     ret = EVP_PKEY_assign(pkey, type, dhkey);
 
-    if (ret)
-        DH_up_ref(dhkey);
+    if (!ret)
+        DH_free(dhkey);
+
     return ret;
 }
 
@@ -968,8 +1010,9 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
 {
     DH *ret = evp_pkey_get0_DH_int(pkey);
 
-    if (ret != NULL)
-        DH_up_ref(ret);
+    if (ret != NULL && !DH_up_ref(ret))
+        ret = NULL;
+
     return ret;
 }
 # endif
@@ -1382,18 +1425,22 @@ int EVP_PKEY_digestsign_supports_digest(EVP_PKEY *pkey, OSSL_LIB_CTX *libctx,
     EVP_MD_CTX_free(ctx);
     return rv;
 }
+#endif  /* !FIPS_MODULE */
 
 int EVP_PKEY_set1_encoded_public_key(EVP_PKEY *pkey, const unsigned char *pub,
                                      size_t publen)
 {
     if (pkey == NULL)
         return 0;
+#ifndef FIPS_MODULE
     if (evp_pkey_is_provided(pkey))
+#endif  /* !FIPS_MODULE */
         return
             EVP_PKEY_set_octet_string_param(pkey,
                                             OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
                                             (unsigned char *)pub, publen);
 
+#ifndef FIPS_MODULE
     if (publen > INT_MAX)
         return 0;
     /* Historically this function was EVP_PKEY_set1_tls_encodedpoint */
@@ -1401,15 +1448,17 @@ int EVP_PKEY_set1_encoded_public_key(EVP_PKEY *pkey, const unsigned char *pub,
                            (void *)pub) <= 0)
         return 0;
     return 1;
+#endif  /* !FIPS_MODULE */
 }
 
 size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY *pkey, unsigned char **ppub)
 {
-    int rv;
-
     if (pkey == NULL)
         return 0;
-    if (evp_pkey_is_provided(pkey)) {
+#ifndef FIPS_MODULE
+    if (evp_pkey_is_provided(pkey))
+#endif
+    {
         size_t return_size = OSSL_PARAM_UNMODIFIED;
         unsigned char *buf;
 
@@ -1438,15 +1487,16 @@ size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY *pkey, unsigned char **ppub)
         return return_size;
     }
 
-
-    rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppub);
-    if (rv <= 0)
-        return 0;
-    return rv;
+#ifndef FIPS_MODULE
+    {
+        int rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppub);
+        if (rv <= 0)
+            return 0;
+        return rv;
+    }
+#endif  /* !FIPS_MODULE */
 }
 
-#endif /* FIPS_MODULE */
-
 /*- All methods below can also be used in FIPS_MODULE */
 
 EVP_PKEY *EVP_PKEY_new(void)
@@ -1676,7 +1726,6 @@ int EVP_PKEY_up_ref(EVP_PKEY *pkey)
     return ((i > 1) ? 1 : 0);
 }
 
-#ifndef FIPS_MODULE
 EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey)
 {
     EVP_PKEY *dup_pk;
@@ -1692,13 +1741,17 @@ EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey)
     if (evp_pkey_is_blank(pkey))
         goto done;
 
-    if (evp_pkey_is_provided(pkey)) {
+#ifndef FIPS_MODULE
+    if (evp_pkey_is_provided(pkey))
+#endif  /* !FIPS_MODULE */
+    {
         if (!evp_keymgmt_util_copy(dup_pk, pkey,
                                    OSSL_KEYMGMT_SELECT_ALL))
             goto err;
         goto done;
     }
 
+#ifndef FIPS_MODULE
     if (evp_pkey_is_legacy(pkey)) {
         const EVP_PKEY_ASN1_METHOD *ameth = pkey->ameth;
 
@@ -1713,9 +1766,11 @@ EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey)
             goto err;
         goto done;
     }
+#endif  /* !FIPS_MODULE */
 
     goto err;
 done:
+#ifndef FIPS_MODULE
     /* copy auxiliary data */
     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EVP_PKEY,
                             &dup_pk->ex_data, &pkey->ex_data))
@@ -1725,12 +1780,14 @@ done:
         if ((dup_pk->attributes = ossl_x509at_dup(pkey->attributes)) == NULL)
             goto err;
     }
+#endif  /* !FIPS_MODULE */
     return dup_pk;
 err:
     EVP_PKEY_free(dup_pk);
     return NULL;
 }
 
+#ifndef FIPS_MODULE
 void evp_pkey_free_legacy(EVP_PKEY *x)
 {
     const EVP_PKEY_ASN1_METHOD *ameth = x->ameth;

+ 25 - 6
libs/openssl/crypto/evp/pmeth_lib.c

@@ -321,9 +321,13 @@ static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx,
     ret->engine = e;
     ret->pmeth = pmeth;
     ret->operation = EVP_PKEY_OP_UNDEFINED;
+
+    if (pkey != NULL && !EVP_PKEY_up_ref(pkey)) {
+        EVP_PKEY_CTX_free(ret);
+        return NULL;
+    }
+
     ret->pkey = pkey;
-    if (pkey != NULL)
-        EVP_PKEY_up_ref(pkey);
 
     if (pmeth != NULL && pmeth->init != NULL) {
         if (pmeth->init(ret) <= 0) {
@@ -461,8 +465,9 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
     if (rctx == NULL)
         return NULL;
 
-    if (pctx->pkey != NULL)
-        EVP_PKEY_up_ref(pctx->pkey);
+    if (pctx->pkey != NULL && !EVP_PKEY_up_ref(pctx->pkey))
+        goto err;
+
     rctx->pkey = pctx->pkey;
     rctx->operation = pctx->operation;
     rctx->libctx = pctx->libctx;
@@ -575,8 +580,9 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
     rctx->engine = pctx->engine;
 # endif
 
-    if (pctx->peerkey != NULL)
-        EVP_PKEY_up_ref(pctx->peerkey);
+    if (pctx->peerkey != NULL && !EVP_PKEY_up_ref(pctx->peerkey))
+        goto err;
+
     rctx->peerkey = pctx->peerkey;
 
     if (pctx->pmeth == NULL) {
@@ -742,6 +748,12 @@ int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
             return
                 ctx->op.encap.kem->get_ctx_params(ctx->op.encap.algctx,
                                                   params);
+        if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
+            && ctx->keymgmt != NULL
+            && ctx->keymgmt->gen_get_params != NULL)
+            return
+                evp_keymgmt_gen_get_params(ctx->keymgmt, ctx->op.keymgmt.genctx,
+                                           params);
         break;
     case EVP_PKEY_STATE_UNKNOWN:
         break;
@@ -788,6 +800,13 @@ const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(const EVP_PKEY_CTX *ctx)
         return ctx->op.encap.kem->gettable_ctx_params(ctx->op.encap.algctx,
                                                       provctx);
     }
+    if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
+            && ctx->keymgmt != NULL
+            && ctx->keymgmt->gen_gettable_params != NULL) {
+        provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(ctx->keymgmt));
+        return ctx->keymgmt->gen_gettable_params(ctx->op.keymgmt.genctx,
+                                                 provctx);
+    }
     return NULL;
 }
 

+ 314 - 0
libs/openssl/crypto/evp/s_lib.c

@@ -0,0 +1,314 @@
+/*
+ * Copyright 2025 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <string.h>
+#include <openssl/params.h>
+#include <openssl/param_build.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+
+#include "internal/common.h"
+#include "internal/provider.h"
+#include "crypto/evp.h"
+#include "evp_local.h"
+
+int EVP_SKEY_export(const EVP_SKEY *skey, int selection,
+                    OSSL_CALLBACK *export_cb, void *export_cbarg)
+{
+    if (skey == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return evp_skeymgmt_export(skey->skeymgmt, skey->keydata, selection, export_cb, export_cbarg);
+}
+
+static EVP_SKEY *evp_skey_alloc(EVP_SKEYMGMT *skeymgmt)
+{
+    EVP_SKEY *skey;
+
+    if (!ossl_assert(skeymgmt != NULL))
+        return NULL;
+
+    if ((skey = OPENSSL_zalloc(sizeof(*skey))) == NULL)
+        return NULL;
+
+    if (!CRYPTO_NEW_REF(&skey->references, 1))
+        goto err;
+
+    skey->lock = CRYPTO_THREAD_lock_new();
+    if (skey->lock == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB);
+        goto err;
+    }
+    skey->skeymgmt = skeymgmt;
+    return skey;
+
+ err:
+    CRYPTO_FREE_REF(&skey->references);
+    CRYPTO_THREAD_lock_free(skey->lock);
+    OPENSSL_free(skey);
+    return NULL;
+}
+
+static EVP_SKEY *evp_skey_alloc_fetch(OSSL_LIB_CTX *libctx,
+                                      const char *skeymgmtname,
+                                      const char *propquery)
+{
+    EVP_SKEYMGMT *skeymgmt;
+    EVP_SKEY *skey;
+
+    skeymgmt = EVP_SKEYMGMT_fetch(libctx, skeymgmtname, propquery);
+    if (skeymgmt == NULL) {
+        /*
+         * if the specific key_type is unknown, attempt to use the generic
+         * key management
+         */
+        skeymgmt = EVP_SKEYMGMT_fetch(libctx, OSSL_SKEY_TYPE_GENERIC, propquery);
+        if (skeymgmt == NULL) {
+            ERR_raise(ERR_LIB_EVP, ERR_R_FETCH_FAILED);
+            return NULL;
+        }
+    }
+
+    skey = evp_skey_alloc(skeymgmt);
+    if (skey == NULL)
+        EVP_SKEYMGMT_free(skeymgmt);
+
+    return skey;
+}
+
+EVP_SKEY *EVP_SKEY_import(OSSL_LIB_CTX *libctx, const char *skeymgmtname, const char *propquery,
+                          int selection, const OSSL_PARAM *params)
+{
+    EVP_SKEY *skey = evp_skey_alloc_fetch(libctx, skeymgmtname, propquery);
+
+    if (skey == NULL)
+        return NULL;
+
+    skey->keydata = evp_skeymgmt_import(skey->skeymgmt, selection, params);
+    if (skey->keydata == NULL)
+        goto err;
+
+    return skey;
+
+ err:
+    EVP_SKEY_free(skey);
+    return NULL;
+}
+
+EVP_SKEY *EVP_SKEY_generate(OSSL_LIB_CTX *libctx, const char *skeymgmtname,
+                            const char *propquery, const OSSL_PARAM *params)
+{
+    EVP_SKEY *skey = evp_skey_alloc_fetch(libctx, skeymgmtname, propquery);
+
+    if (skey == NULL)
+        return NULL;
+
+    skey->keydata = evp_skeymgmt_generate(skey->skeymgmt, params);
+    if (skey->keydata == NULL)
+        goto err;
+
+    return skey;
+
+ err:
+    EVP_SKEY_free(skey);
+    return NULL;
+}
+
+struct raw_key_details_st {
+    const void **key;
+    size_t *len;
+};
+
+static int get_secret_key(const OSSL_PARAM params[], void *arg)
+{
+    const OSSL_PARAM *p = NULL;
+    struct raw_key_details_st *raw_key = arg;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_SKEY_PARAM_RAW_BYTES)) != NULL)
+        return OSSL_PARAM_get_octet_string_ptr(p, raw_key->key, raw_key->len);
+
+    return 0;
+}
+
+int EVP_SKEY_get0_raw_key(const EVP_SKEY *skey, const unsigned char **key,
+                          size_t *len)
+{
+    struct raw_key_details_st raw_key;
+
+    if (skey == NULL || key == NULL || len == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    raw_key.key = (const void **)key;
+    raw_key.len = len;
+
+    return evp_skeymgmt_export(skey->skeymgmt, skey->keydata,
+                               OSSL_SKEYMGMT_SELECT_SECRET_KEY,
+                               get_secret_key, &raw_key);
+}
+
+EVP_SKEY *EVP_SKEY_import_raw_key(OSSL_LIB_CTX *libctx, const char *skeymgmtname,
+                                  unsigned char *key, size_t keylen,
+                                  const char *propquery)
+{
+    OSSL_PARAM params[2];
+
+    params[0] = OSSL_PARAM_construct_octet_string(OSSL_SKEY_PARAM_RAW_BYTES,
+                                                  (void *)key, keylen);
+    params[1] = OSSL_PARAM_construct_end();
+
+    return EVP_SKEY_import(libctx, skeymgmtname, propquery,
+                           OSSL_SKEYMGMT_SELECT_SECRET_KEY, params);
+}
+
+int EVP_SKEY_up_ref(EVP_SKEY *skey)
+{
+    int i;
+
+    if (CRYPTO_UP_REF(&skey->references, &i) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("EVP_SKEY", i, skey);
+    REF_ASSERT_ISNT(i < 2);
+    return i > 1 ? 1 : 0;
+}
+
+void EVP_SKEY_free(EVP_SKEY *skey)
+{
+    int i;
+
+    if (skey == NULL)
+        return;
+
+    CRYPTO_DOWN_REF(&skey->references, &i);
+    REF_PRINT_COUNT("EVP_SKEY", i, skey);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+    evp_skeymgmt_freedata(skey->skeymgmt, skey->keydata);
+
+    EVP_SKEYMGMT_free(skey->skeymgmt);
+
+    CRYPTO_THREAD_lock_free(skey->lock);
+    CRYPTO_FREE_REF(&skey->references);
+    OPENSSL_free(skey);
+}
+
+const char *EVP_SKEY_get0_key_id(const EVP_SKEY *skey)
+{
+    if (skey == NULL)
+        return NULL;
+
+    if (skey->skeymgmt->get_key_id)
+        return skey->skeymgmt->get_key_id(skey->keydata);
+
+    return NULL;
+}
+
+const char *EVP_SKEY_get0_skeymgmt_name(const EVP_SKEY *skey)
+{
+    if (skey == NULL)
+        return NULL;
+
+    return skey->skeymgmt->type_name;
+
+}
+
+const char *EVP_SKEY_get0_provider_name(const EVP_SKEY *skey)
+{
+    if (skey == NULL)
+        return NULL;
+
+    return ossl_provider_name(skey->skeymgmt->prov);
+}
+
+int EVP_SKEY_is_a(const EVP_SKEY *skey, const char *name)
+{
+    if (skey == NULL)
+        return 0;
+
+    return EVP_SKEYMGMT_is_a(skey->skeymgmt, name);
+}
+
+struct transfer_cb_ctx {
+    int selection;
+    EVP_SKEYMGMT *skeymgmt;
+    void *keydata;
+};
+
+static int transfer_cb(const OSSL_PARAM params[], void *arg)
+{
+    struct transfer_cb_ctx *ctx = arg;
+
+    ctx->keydata = evp_skeymgmt_import(ctx->skeymgmt, ctx->selection, params);
+    return 1;
+}
+
+EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx,
+                               OSSL_PROVIDER *prov, const char *propquery)
+{
+    struct transfer_cb_ctx ctx = { 0 };
+    EVP_SKEYMGMT *skeymgmt = NULL;
+    EVP_SKEY *ret = NULL;
+
+    if (skey == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+
+    if (prov != NULL) {
+        if (skey->skeymgmt->prov == prov)
+            skeymgmt = skey->skeymgmt;
+        else
+            skeymgmt = evp_skeymgmt_fetch_from_prov(prov, skey->skeymgmt->type_name,
+                                                    propquery);
+    } else {
+        /* If no provider, get the default skeymgmt */
+        skeymgmt = EVP_SKEYMGMT_fetch(libctx, skey->skeymgmt->type_name,
+                                      propquery);
+    }
+    if (skeymgmt == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_FETCH_FAILED);
+        return NULL;
+    }
+
+    /* Short-circuit if destination provider is the same as origin */
+    if (skey->skeymgmt->name_id == skeymgmt->name_id
+        && skey->skeymgmt->prov == skeymgmt->prov) {
+        if (!EVP_SKEY_up_ref(skey))
+            goto err;
+        EVP_SKEYMGMT_free(skeymgmt);
+        return skey;
+    }
+
+    ctx.selection = OSSL_SKEYMGMT_SELECT_ALL;
+    ctx.skeymgmt = skeymgmt;
+
+    if (!EVP_SKEY_export(skey, ctx.selection, transfer_cb, &ctx))
+        goto err;
+
+    if (ctx.keydata == NULL)
+        goto err;
+
+    ret = evp_skey_alloc(skeymgmt);
+    if (ret == NULL)
+        goto err;
+
+    ret->keydata = ctx.keydata;
+
+    return ret;
+
+ err:
+    EVP_SKEYMGMT_free(skeymgmt);
+    EVP_SKEY_free(ret);
+    return NULL;
+}

File diff suppressed because it is too large
+ 639 - 162
libs/openssl/crypto/evp/signature.c


+ 242 - 0
libs/openssl/crypto/evp/skeymgmt_meth.c

@@ -0,0 +1,242 @@
+/*
+ * Copyright 2025 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/crypto.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include "internal/core.h"
+#include "internal/provider.h"
+#include "internal/refcount.h"
+#include "crypto/evp.h"
+#include "evp_local.h"
+
+void *evp_skeymgmt_generate(const EVP_SKEYMGMT *skeymgmt, const OSSL_PARAM params[])
+{
+    void *provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt));
+
+    return (skeymgmt->generate != NULL) ? skeymgmt->generate(provctx, params) : NULL;
+}
+
+void *evp_skeymgmt_import(const EVP_SKEYMGMT *skeymgmt, int selection, const OSSL_PARAM params[])
+{
+    void *provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt));
+
+    /* This is mandatory, no need to check for its presence */
+    return skeymgmt->import(provctx, selection, params);
+}
+
+int evp_skeymgmt_export(const EVP_SKEYMGMT *skeymgmt, void *keydata,
+                        int selection, OSSL_CALLBACK *param_cb, void *cbarg)
+{
+    /* This is mandatory, no need to check for its presence */
+    return skeymgmt->export(keydata, selection, param_cb, cbarg);
+}
+
+void evp_skeymgmt_freedata(const EVP_SKEYMGMT *skeymgmt, void *keydata)
+{
+    /* This is mandatory, no need to check for its presence */
+    skeymgmt->free(keydata);
+}
+
+static void *skeymgmt_new(void)
+{
+    EVP_SKEYMGMT *skeymgmt = NULL;
+
+    if ((skeymgmt = OPENSSL_zalloc(sizeof(*skeymgmt))) == NULL)
+        return NULL;
+    if (!CRYPTO_NEW_REF(&skeymgmt->refcnt, 1)) {
+        EVP_SKEYMGMT_free(skeymgmt);
+        return NULL;
+    }
+    return skeymgmt;
+}
+
+static void *skeymgmt_from_algorithm(int name_id,
+                                     const OSSL_ALGORITHM *algodef,
+                                     OSSL_PROVIDER *prov)
+{
+    const OSSL_DISPATCH *fns = algodef->implementation;
+    EVP_SKEYMGMT *skeymgmt = NULL;
+
+    if ((skeymgmt = skeymgmt_new()) == NULL)
+        return NULL;
+
+    skeymgmt->name_id = name_id;
+    if ((skeymgmt->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
+        EVP_SKEYMGMT_free(skeymgmt);
+        return NULL;
+    }
+    skeymgmt->description = algodef->algorithm_description;
+
+    for (; fns->function_id != 0; fns++) {
+        switch (fns->function_id) {
+        case OSSL_FUNC_SKEYMGMT_FREE:
+            if (skeymgmt->free == NULL)
+                skeymgmt->free = OSSL_FUNC_skeymgmt_free(fns);
+            break;
+        case OSSL_FUNC_SKEYMGMT_IMPORT:
+            if (skeymgmt->import == NULL)
+                skeymgmt->import = OSSL_FUNC_skeymgmt_import(fns);
+            break;
+        case OSSL_FUNC_SKEYMGMT_EXPORT:
+            if (skeymgmt->export == NULL)
+                skeymgmt->export = OSSL_FUNC_skeymgmt_export(fns);
+            break;
+        case OSSL_FUNC_SKEYMGMT_GENERATE:
+            if (skeymgmt->generate == NULL)
+                skeymgmt->generate = OSSL_FUNC_skeymgmt_generate(fns);
+            break;
+        case OSSL_FUNC_SKEYMGMT_GET_KEY_ID:
+            if (skeymgmt->get_key_id == NULL)
+                skeymgmt->get_key_id = OSSL_FUNC_skeymgmt_get_key_id(fns);
+            break;
+        case OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS:
+            if (skeymgmt->imp_params == NULL)
+                skeymgmt->imp_params = OSSL_FUNC_skeymgmt_imp_settable_params(fns);
+            break;
+        case OSSL_FUNC_SKEYMGMT_GEN_SETTABLE_PARAMS:
+            if (skeymgmt->gen_params == NULL)
+                skeymgmt->gen_params = OSSL_FUNC_skeymgmt_gen_settable_params(fns);
+            break;
+        }
+    }
+
+    /* Check that the provider is sensible */
+    if (skeymgmt->free == NULL
+        || skeymgmt->import == NULL
+        || skeymgmt->export == NULL) {
+        EVP_SKEYMGMT_free(skeymgmt);
+        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
+        return NULL;
+    }
+
+    if (!ossl_provider_up_ref(prov)) {
+        EVP_SKEYMGMT_free(skeymgmt);
+        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+        return NULL;
+    }
+    skeymgmt->prov = prov;
+
+    return skeymgmt;
+}
+
+EVP_SKEYMGMT *evp_skeymgmt_fetch_from_prov(OSSL_PROVIDER *prov,
+                                           const char *name,
+                                           const char *properties)
+{
+    return evp_generic_fetch_from_prov(prov,
+                                       OSSL_OP_SKEYMGMT,
+                                       name, properties,
+                                       skeymgmt_from_algorithm,
+                                       (int (*)(void *))EVP_SKEYMGMT_up_ref,
+                                       (void (*)(void *))EVP_SKEYMGMT_free);
+}
+
+EVP_SKEYMGMT *EVP_SKEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
+                                 const char *properties)
+{
+    return evp_generic_fetch(ctx, OSSL_OP_SKEYMGMT, algorithm, properties,
+                             skeymgmt_from_algorithm,
+                             (int (*)(void *))EVP_SKEYMGMT_up_ref,
+                             (void (*)(void *))EVP_SKEYMGMT_free);
+}
+
+int EVP_SKEYMGMT_up_ref(EVP_SKEYMGMT *skeymgmt)
+{
+    int ref = 0;
+
+    CRYPTO_UP_REF(&skeymgmt->refcnt, &ref);
+    return 1;
+}
+
+void EVP_SKEYMGMT_free(EVP_SKEYMGMT *skeymgmt)
+{
+    int ref = 0;
+
+    if (skeymgmt == NULL)
+        return;
+
+    CRYPTO_DOWN_REF(&skeymgmt->refcnt, &ref);
+    if (ref > 0)
+        return;
+    OPENSSL_free(skeymgmt->type_name);
+    ossl_provider_free(skeymgmt->prov);
+    CRYPTO_FREE_REF(&skeymgmt->refcnt);
+    OPENSSL_free(skeymgmt);
+}
+
+const OSSL_PROVIDER *EVP_SKEYMGMT_get0_provider(const EVP_SKEYMGMT *skeymgmt)
+{
+    return (skeymgmt != NULL) ? skeymgmt->prov : NULL;
+}
+
+const char *EVP_SKEYMGMT_get0_description(const EVP_SKEYMGMT *skeymgmt)
+{
+    return (skeymgmt != NULL) ? skeymgmt->description : NULL;
+}
+
+const char *EVP_SKEYMGMT_get0_name(const EVP_SKEYMGMT *skeymgmt)
+{
+    return (skeymgmt != NULL) ? skeymgmt->type_name : NULL;
+}
+
+int EVP_SKEYMGMT_is_a(const EVP_SKEYMGMT *skeymgmt, const char *name)
+{
+    return skeymgmt != NULL
+        && evp_is_a(skeymgmt->prov, skeymgmt->name_id, NULL, name);
+}
+
+void EVP_SKEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx,
+                                  void (*fn)(EVP_SKEYMGMT *skeymgmt, void *arg),
+                                  void *arg)
+{
+    evp_generic_do_all(libctx, OSSL_OP_SKEYMGMT,
+                       (void (*)(void *, void *))fn, arg,
+                       skeymgmt_from_algorithm,
+                       (int (*)(void *))EVP_SKEYMGMT_up_ref,
+                       (void (*)(void *))EVP_SKEYMGMT_free);
+}
+
+int EVP_SKEYMGMT_names_do_all(const EVP_SKEYMGMT *skeymgmt,
+                              void (*fn)(const char *name, void *data),
+                              void *data)
+{
+    if (skeymgmt == NULL)
+        return 0;
+
+    if (skeymgmt->prov != NULL)
+        return evp_names_do_all(skeymgmt->prov, skeymgmt->name_id, fn, data);
+
+    return 1;
+}
+
+const OSSL_PARAM *EVP_SKEYMGMT_get0_gen_settable_params(const EVP_SKEYMGMT *skeymgmt)
+{
+    void *provctx = NULL;
+
+    if (skeymgmt == NULL)
+        return 0;
+
+    provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt));
+
+    return (skeymgmt->gen_params != NULL) ? skeymgmt->gen_params(provctx) : NULL;
+}
+
+const OSSL_PARAM *EVP_SKEYMGMT_get0_imp_settable_params(const EVP_SKEYMGMT *skeymgmt)
+{
+    void *provctx = NULL;
+
+    if (skeymgmt == NULL)
+        return 0;
+
+    provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt));
+
+    return (skeymgmt->imp_params != NULL) ? skeymgmt->imp_params(provctx) : NULL;
+}

+ 9 - 1
libs/openssl/crypto/ffc/ffc_params.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2024 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
@@ -27,11 +27,19 @@ void ossl_ffc_params_init(FFC_PARAMS *params)
 
 void ossl_ffc_params_cleanup(FFC_PARAMS *params)
 {
+#ifdef OPENSSL_PEDANTIC_ZEROIZATION
+    BN_clear_free(params->p);
+    BN_clear_free(params->q);
+    BN_clear_free(params->g);
+    BN_clear_free(params->j);
+    OPENSSL_clear_free(params->seed, params->seedlen);
+#else
     BN_free(params->p);
     BN_free(params->q);
     BN_free(params->g);
     BN_free(params->j);
     OPENSSL_free(params->seed);
+#endif
     ossl_ffc_params_init(params);
 }
 

Some files were not shown because too many files changed in this diff