Browse Source

Merge branch 'thirdparty_dev' into dev

Source commit: 25c89439beb09a535aa58d44b729f0f772e575ed
Martin Prikryl 1 year ago
parent
commit
b1ef401853
100 changed files with 3163 additions and 839 deletions
  1. 144 27
      libs/openssl/INSTALL.md
  2. 1 1
      libs/openssl/crypto/aria/aria.c
  3. 6 11
      libs/openssl/crypto/asn1/a_bitstr.c
  4. 3 3
      libs/openssl/crypto/asn1/a_d2i_fp.c
  5. 1 3
      libs/openssl/crypto/asn1/a_digest.c
  6. 2 4
      libs/openssl/crypto/asn1/a_dup.c
  7. 2 4
      libs/openssl/crypto/asn1/a_i2d_fp.c
  8. 9 11
      libs/openssl/crypto/asn1/a_int.c
  9. 3 6
      libs/openssl/crypto/asn1/a_mbstr.c
  10. 5 15
      libs/openssl/crypto/asn1/a_object.c
  11. 15 25
      libs/openssl/crypto/asn1/a_sign.c
  12. 1 3
      libs/openssl/crypto/asn1/a_strex.c
  13. 8 8
      libs/openssl/crypto/asn1/a_strnid.c
  14. 78 5
      libs/openssl/crypto/asn1/a_time.c
  15. 7 8
      libs/openssl/crypto/asn1/a_verify.c
  16. 1 4
      libs/openssl/crypto/asn1/ameth_lib.c
  17. 16 18
      libs/openssl/crypto/asn1/asn1_gen.c
  18. 7 4
      libs/openssl/crypto/asn1/asn1_lib.c
  19. 2 0
      libs/openssl/crypto/asn1/asn1_local.h
  20. 13 12
      libs/openssl/crypto/asn1/asn_mime.c
  21. 1 3
      libs/openssl/crypto/asn1/asn_moid.c
  22. 1 1
      libs/openssl/crypto/asn1/asn_mstbl.c
  23. 17 5
      libs/openssl/crypto/asn1/asn_pack.c
  24. 5 5
      libs/openssl/crypto/asn1/bio_asn1.c
  25. 2 6
      libs/openssl/crypto/asn1/bio_ndef.c
  26. 0 1
      libs/openssl/crypto/asn1/f_int.c
  27. 0 1
      libs/openssl/crypto/asn1/f_string.c
  28. 2 3
      libs/openssl/crypto/asn1/i2d_evp.c
  29. 9 9
      libs/openssl/crypto/asn1/p5_pbe.c
  30. 73 43
      libs/openssl/crypto/asn1/p5_pbev2.c
  31. 62 37
      libs/openssl/crypto/asn1/p5_scrypt.c
  32. 2 4
      libs/openssl/crypto/asn1/standard_methods.h
  33. 7 9
      libs/openssl/crypto/asn1/tasn_dec.c
  34. 3 9
      libs/openssl/crypto/asn1/tasn_enc.c
  35. 14 16
      libs/openssl/crypto/asn1/tasn_new.c
  36. 1 3
      libs/openssl/crypto/asn1/tasn_prn.c
  37. 13 11
      libs/openssl/crypto/asn1/tasn_utl.c
  38. 34 25
      libs/openssl/crypto/asn1/x_algor.c
  39. 1 3
      libs/openssl/crypto/asn1/x_info.c
  40. 3 7
      libs/openssl/crypto/asn1/x_int64.c
  41. 6 7
      libs/openssl/crypto/asn1/x_pkey.c
  42. 3 1
      libs/openssl/crypto/async/arch/async_null.h
  43. 3 0
      libs/openssl/crypto/async/arch/async_posix.h
  44. 16 1
      libs/openssl/crypto/async/arch/async_win.c
  45. 3 1
      libs/openssl/crypto/async/arch/async_win.h
  46. 7 13
      libs/openssl/crypto/async/async.c
  47. 1 3
      libs/openssl/crypto/async/async_wait.c
  48. 1 1
      libs/openssl/crypto/bf/bf_local.h
  49. 6 7
      libs/openssl/crypto/bio/bf_buff.c
  50. 1 3
      libs/openssl/crypto/bio/bf_nbio.c
  51. 46 25
      libs/openssl/crypto/bio/bio_addr.c
  52. 21 1
      libs/openssl/crypto/bio/bio_cb.c
  53. 29 1
      libs/openssl/crypto/bio/bio_err.c
  54. 114 18
      libs/openssl/crypto/bio/bio_lib.c
  55. 9 14
      libs/openssl/crypto/bio/bio_local.h
  56. 28 8
      libs/openssl/crypto/bio/bio_meth.c
  57. 4 10
      libs/openssl/crypto/bio/bio_print.c
  58. 44 5
      libs/openssl/crypto/bio/bio_sock.c
  59. 113 0
      libs/openssl/crypto/bio/bio_sock2.c
  60. 5 3
      libs/openssl/crypto/bio/bss_acpt.c
  61. 3 7
      libs/openssl/crypto/bio/bss_bio.c
  62. 273 10
      libs/openssl/crypto/bio/bss_conn.c
  63. 1328 0
      libs/openssl/crypto/bio/bss_dgram_pair.c
  64. 1 1
      libs/openssl/crypto/bio/bss_fd.c
  65. 1 1
      libs/openssl/crypto/bio/bss_file.c
  66. 4 4
      libs/openssl/crypto/bio/bss_log.c
  67. 1 1
      libs/openssl/crypto/bio/bss_mem.c
  68. 77 5
      libs/openssl/crypto/bio/bss_sock.c
  69. 5 7
      libs/openssl/crypto/bio/ossl_core_bio.c
  70. 2 4
      libs/openssl/crypto/bn/bn_blind.c
  71. 1 1
      libs/openssl/crypto/bn/bn_const.c
  72. 2 6
      libs/openssl/crypto/bn/bn_conv.c
  73. 3 9
      libs/openssl/crypto/bn/bn_ctx.c
  74. 30 9
      libs/openssl/crypto/bn/bn_exp.c
  75. 1 1
      libs/openssl/crypto/bn/bn_gcd.c
  76. 5 15
      libs/openssl/crypto/bn/bn_gf2m.c
  77. 3 7
      libs/openssl/crypto/bn/bn_intern.c
  78. 180 92
      libs/openssl/crypto/bn/bn_lib.c
  79. 5 2
      libs/openssl/crypto/bn/bn_local.h
  80. 12 4
      libs/openssl/crypto/bn/bn_mod.c
  81. 1 3
      libs/openssl/crypto/bn/bn_mont.c
  82. 1 1
      libs/openssl/crypto/bn/bn_mul.c
  83. 1 1
      libs/openssl/crypto/bn/bn_nist.c
  84. 2 4
      libs/openssl/crypto/bn/bn_prime.c
  85. 1 3
      libs/openssl/crypto/bn/bn_rand.c
  86. 1 3
      libs/openssl/crypto/bn/bn_recp.c
  87. 1 1
      libs/openssl/crypto/bn/bn_rsa_fips186_4.c
  88. 1 1
      libs/openssl/crypto/bn/rsaz_exp.h
  89. 3 7
      libs/openssl/crypto/buffer/buffer.c
  90. 1 46
      libs/openssl/crypto/cast/cast_local.h
  91. 1 1
      libs/openssl/crypto/chacha/chacha_enc.c
  92. 34 9
      libs/openssl/crypto/cmac/cmac.c
  93. 5 0
      libs/openssl/crypto/cmp/cmp_err.c
  94. 37 6
      libs/openssl/crypto/cmp/cmp_local.h
  95. 4 4
      libs/openssl/crypto/cmp/cmp_util.c
  96. 2 1
      libs/openssl/crypto/cms/cms_asn1.c
  97. 1 1
      libs/openssl/crypto/cms/cms_dd.c
  98. 5 9
      libs/openssl/crypto/cms/cms_enc.c
  99. 88 57
      libs/openssl/crypto/cms/cms_env.c
  100. 2 0
      libs/openssl/crypto/cms/cms_err.c

+ 144 - 27
libs/openssl/INSTALL.md

@@ -19,7 +19,7 @@ Table of Contents
    - [Build Type](#build-type)
    - [Directories](#directories)
    - [Compiler Warnings](#compiler-warnings)
-   - [ZLib Flags](#zlib-flags)
+   - [Compression Algorithm Flags](#compression-algorithm-flags)
    - [Seeding the Random Generator](#seeding-the-random-generator)
    - [Setting the FIPS HMAC key](#setting-the-FIPS-HMAC-key)
    - [Enable and Disable Features](#enable-and-disable-features)
@@ -120,21 +120,11 @@ represents one of the four commands
 Arguments
 ---------
 
-**Mandatory arguments** are enclosed in double curly braces.
-A simple example would be
+**Optional Arguments** are enclosed in square brackets.
 
-    $ type {{ filename }}
+    [option...]
 
-which is to be understood to use the command `type` on some file name
-determined by the user.
-
-**Optional Arguments** are enclosed in double square brackets.
-
-    [[ options ]]
-
-Note that the notation assumes spaces around `{`, `}`, `[`, `]`, `{{`, `}}` and
-`[[`, `]]`.  This is to differentiate from OpenVMS directory
-specifications, which also use [ and ], but without spaces.
+A trailing ellipsis means that more than one could be specified.
 
 Quick Installation Guide
 ========================
@@ -177,8 +167,9 @@ issue the following commands to build OpenSSL.
 As mentioned in the [Choices](#choices) section, you need to pick one
 of the four Configure targets in the first command.
 
-Most likely you will be using the `VC-WIN64A` target for 64bit Windows
-binaries (AMD64) or `VC-WIN32` for 32bit Windows binaries (X86).
+Most likely you will be using the `VC-WIN64A`/`VC-WIN64A-HYBRIDCRT` target for
+64bit Windows binaries (AMD64) or `VC-WIN32`/`VC-WIN32-HYBRIDCRT` for 32bit
+Windows binaries (X86).
 The other two options are `VC-WIN64I` (Intel IA64, Itanium) and
 `VC-CE` (Windows CE) are rather uncommon nowadays.
 
@@ -391,8 +382,39 @@ for OpenSSL development.  It only works when using gcc or clang as the compiler.
 If you are developing a patch for OpenSSL then it is recommended that you use
 this option where possible.
 
-ZLib Flags
-----------
+Compression Algorithm Flags
+---------------------------
+
+### with-brotli-include
+
+    --with-brotli-include=DIR
+
+The directory for the location of the brotli include files (i.e. the location
+of the **brotli** include directory).  This option is only necessary if
+[enable-brotli](#enable-brotli) is used and the include files are not already
+on the system include path.
+
+### with-brotli-lib
+
+    --with-brotli-lib=LIB
+
+**On Unix**: this is the directory containing the brotli libraries.
+If not provided, the system library path will be used.
+
+The names of the libraries are:
+
+* libbrotlicommon.a or libbrotlicommon.so
+* libbrotlidec.a or libbrotlidec.so
+* libbrotlienc.a or libbrotlienc.so
+
+**On Windows:** this is the directory containing the brotli libraries.
+If not provided, the system library path will be used.
+
+The names of the libraries are:
+
+* brotlicommon.lib
+* brotlidec.lib
+* brotlienc.lib
 
 ### with-zlib-include
 
@@ -418,6 +440,32 @@ then this flag is optional and defaults to `ZLIB1` if not provided.
 This flag is optional and if not provided then `GNV$LIBZSHR`, `GNV$LIBZSHR32`
 or `GNV$LIBZSHR64` is used by default depending on the pointer size chosen.
 
+### with-zstd-include
+
+    --with-zstd-include=DIR
+
+The directory for the location of the Zstd include file. This option is only
+necessary if [enable-std](#enable-zstd) is used and the include file is not
+already on the system include path.
+
+OpenSSL requires Zstd 1.4 or greater. The Linux kernel source contains a
+*zstd.h* file that is not compatible with the 1.4.x Zstd distribution, the
+compilation will generate an error if the Linux *zstd.h* is included before
+(or instead of) the Zstd distribution header.
+
+### with-zstd-lib
+
+    --with-zstd-lib=LIB
+
+**On Unix**: this is the directory containing the Zstd library.
+If not provided the system library path will be used.
+
+**On Windows:** this is the filename of the Zstd library (with or
+without a path).  This flag must be provided if the
+[enable-zstd-dynamic](#enable-zstd-dynamic) option is not also used.
+If `zstd-dynamic` is used then this flag is optional and defaults
+to `LIBZSTD` if not provided.
+
 Seeding the Random Generator
 ----------------------------
 
@@ -535,6 +583,11 @@ access to algorithm internals that are not normally accessible.
 Additional information related to ACVP can be found at
 <https://github.com/usnistgov/ACVP>.
 
+### no-apps
+
+Do not build apps, e.g. the openssl program. This is handy for minimization.
+This option also disables tests.
+
 ### no-asm
 
 Do not use assembler code.
@@ -565,6 +618,17 @@ Typically OpenSSL will automatically load human readable error strings.  For a
 statically linked application this may be undesirable if small executable size
 is an objective.
 
+### enable-brotli
+
+Build with support for brotli compression/decompression.
+
+### enable-brotli-dynamic
+
+Like the enable-brotli option, but has OpenSSL load the brotli library dynamically
+when needed.
+
+This is only supported on systems where loading of shared libraries is supported.
+
 ### no-autoload-config
 
 Don't automatically load the default `openssl.cnf` file.
@@ -652,6 +716,10 @@ Don't build support for datagram based BIOs.
 
 Selecting this option will also force the disabling of DTLS.
 
+### no-docs
+
+Don't build and install documentation, i.e. manual pages in various forms.
+
 ### no-dso
 
 Don't build support for loading Dynamic Shared Objects (DSO)
@@ -747,6 +815,10 @@ Note that if this feature is enabled then GOST ciphersuites are only available
 if the GOST algorithms are also available through loading an externally supplied
 engine.
 
+### no-http
+
+Disable HTTP support.
+
 ### no-legacy
 
 Don't build the legacy provider.
@@ -842,6 +914,10 @@ Do not create shared libraries, only static ones.
 
 See [Notes on shared libraries](#notes-on-shared-libraries) below.
 
+### no-sm2-precomp
+
+Disable using the SM2 precomputed table on aarch64 to make the library smaller.
+
 ### no-sock
 
 Don't build support for socket BIOs.
@@ -895,6 +971,14 @@ tests also use the command line applications, the tests will also be skipped.
 
 Don't build test programs or run any tests.
 
+### enable-tfo
+
+Build with support for TCP Fast Open (RFC7413). Supported on Linux, macOS and FreeBSD.
+
+### no-quic
+
+Don't build with QUIC support.
+
 ### no-threads
 
 Don't build with support for multi-threaded applications.
@@ -907,6 +991,27 @@ will usually require additional system-dependent options!
 
 See [Notes on multi-threading](#notes-on-multi-threading) below.
 
+### no-thread-pool
+
+Don't build with support for thread pool functionality.
+
+### thread-pool
+
+Build with thread pool functionality. If enabled, OpenSSL algorithms may
+use the thread pool to perform parallel computation. This option in itself
+does not enable OpenSSL to spawn new threads. Currently the only supported
+thread pool mechanism is the default thread pool.
+
+### no-default-thread-pool
+
+Don't build with support for default thread pool functionality.
+
+### default-thread-pool
+
+Build with default thread pool functionality. If enabled, OpenSSL may create
+and manage threads up to a maximum number of threads authorized by the
+application. Supported on POSIX compliant platforms and Windows.
+
 ### enable-trace
 
 Build with support for the integrated tracing api.
@@ -959,6 +1064,17 @@ when needed.
 
 This is only supported on systems where loading of shared libraries is supported.
 
+### enable-zstd
+
+Build with support for Zstd compression/decompression.
+
+### enable-zstd-dynamic
+
+Like the enable-zstd option, but has OpenSSL load the Zstd library dynamically
+when needed.
+
+This is only supported on systems where loading of shared libraries is supported.
+
 ### 386
 
 In 32-bit x86 builds, use the 80386 instruction set only in assembly modules
@@ -1163,15 +1279,15 @@ the same.
 
 #### Unix / Linux / macOS
 
-    $ ./Configure [[ options ]]
+    $ ./Configure [options...]
 
 #### OpenVMS
 
-    $ perl Configure [[ options ]]
+    $ perl Configure [options...]
 
 #### Windows
 
-    $ perl Configure [[ options ]]
+    $ perl Configure [options...]
 
 ### Manual Configuration
 
@@ -1193,12 +1309,13 @@ When you have identified your system (and if necessary compiler) use this
 name as the argument to `Configure`.  For example, a `linux-elf` user would
 run:
 
-    $ ./Configure linux-elf [[ options ]]
+    $ ./Configure linux-elf [options...]
 
 ### Creating your own Configuration
 
 If your system isn't listed, you will have to create a configuration
-file named `Configurations/{{ something }}.conf` and add the correct
+file named `Configurations/YOURFILENAME.conf` (replace `YOURFILENAME`
+with a filename of your choosing) and add the correct
 configuration for your system.  See the available configs as examples
 and read [Configurations/README.md](Configurations/README.md) and
 [Configurations/README-design.md](Configurations/README-design.md)
@@ -1230,21 +1347,21 @@ directory and invoking the configuration commands from there.
 
     $ mkdir /var/tmp/openssl-build
     $ cd /var/tmp/openssl-build
-    $ /PATH/TO/OPENSSL/SOURCE/Configure [[ options ]]
+    $ /PATH/TO/OPENSSL/SOURCE/Configure [options...]
 
 #### OpenVMS example
 
     $ set default sys$login:
     $ create/dir [.tmp.openssl-build]
     $ set default [.tmp.openssl-build]
-    $ perl D:[PATH.TO.OPENSSL.SOURCE]Configure [[ options ]]
+    $ perl D:[PATH.TO.OPENSSL.SOURCE]Configure [options...]
 
 #### Windows example
 
     $ C:
     $ mkdir \temp-openssl
     $ cd \temp-openssl
-    $ perl d:\PATH\TO\OPENSSL\SOURCE\Configure [[ options ]]
+    $ perl d:\PATH\TO\OPENSSL\SOURCE\Configure [options...]
 
 Paths can be relative just as well as absolute.  `Configure` will do its best
 to translate them to relative paths whenever possible.
@@ -1465,7 +1582,7 @@ over the build process.  Typically these should be defined prior to running
 
     PERL
                    The name of the Perl executable to use when building OpenSSL.
-                   Only needed if builing should use a different Perl executable
+                   Only needed if building should use a different Perl executable
                    than what is used to run the Configure script.
 
     RANLIB

+ 1 - 1
libs/openssl/crypto/aria/aria.c

@@ -498,7 +498,7 @@ void ossl_aria_encrypt(const unsigned char *in, unsigned char *out,
     ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
     rk++;
 
-    while(Nr -= 2){
+    while ((Nr -= 2) > 0) {
         ARIA_SUBST_DIFF_EVEN(reg0, reg1, reg2, reg3);
         ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
         rk++;

+ 6 - 11
libs/openssl/crypto/asn1/a_bitstr.c

@@ -82,7 +82,7 @@ ASN1_BIT_STRING *ossl_c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
     ASN1_BIT_STRING *ret = NULL;
     const unsigned char *p;
     unsigned char *s;
-    int i;
+    int i = 0;
 
     if (len < 1) {
         i = ASN1_R_STRING_TOO_SHORT;
@@ -110,13 +110,11 @@ ASN1_BIT_STRING *ossl_c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
      * We do this to preserve the settings.  If we modify the settings, via
      * the _set_bit function, we will recalculate on output
      */
-    ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
-    ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */
+    ossl_asn1_string_set_bits_left(ret, i);
 
     if (len-- > 1) {            /* using one because of the bits left byte */
         s = OPENSSL_malloc((int)len);
         if (s == NULL) {
-            i = ERR_R_MALLOC_FAILURE;
             goto err;
         }
         memcpy(s, p, (int)len);
@@ -125,16 +123,15 @@ ASN1_BIT_STRING *ossl_c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
     } else
         s = NULL;
 
-    ret->length = (int)len;
-    OPENSSL_free(ret->data);
-    ret->data = s;
+    ASN1_STRING_set0(ret, s, (int)len);
     ret->type = V_ASN1_BIT_STRING;
     if (a != NULL)
         (*a) = ret;
     *pp = p;
     return ret;
  err:
-    ERR_raise(ERR_LIB_ASN1, i);
+    if (i != 0)
+        ERR_raise(ERR_LIB_ASN1, i);
     if ((a == NULL) || (*a != ret))
         ASN1_BIT_STRING_free(ret);
     return NULL;
@@ -166,10 +163,8 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
         if (!value)
             return 1;         /* Don't need to set */
         c = OPENSSL_clear_realloc(a->data, a->length, w + 1);
-        if (c == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        if (c == NULL)
             return 0;
-        }
         if (w + 1 - a->length > 0)
             memset(c + a->length, 0, w + 1 - a->length);
         a->data = c;

+ 3 - 3
libs/openssl/crypto/asn1/a_d2i_fp.c

@@ -123,7 +123,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
 
     b = BUF_MEM_new();
     if (b == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB);
         return -1;
     }
 
@@ -134,7 +134,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
             want -= diff;
 
             if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+                ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB);
                 goto err;
             }
             i = BIO_read(in, &(b->data[len]), want);
@@ -206,7 +206,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
                     size_t chunk = want > chunk_max ? chunk_max : want;
 
                     if (!BUF_MEM_grow_clean(b, len + chunk)) {
-                        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+                        ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB);
                         goto err;
                     }
                     want -= chunk;

+ 1 - 3
libs/openssl/crypto/asn1/a_digest.c

@@ -36,10 +36,8 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
         ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR);
         return 0;
     }
-    if ((str = OPENSSL_malloc(inl)) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if ((str = OPENSSL_malloc(inl)) == NULL)
         return 0;
-    }
     p = str;
     i2d(data, &p);
 

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

@@ -28,10 +28,8 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x)
         return NULL;
 
     b = OPENSSL_malloc(i + 10);
-    if (b == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (b == NULL)
         return NULL;
-    }
     p = b;
     i = i2d(x, &p);
     p2 = b;
@@ -78,7 +76,7 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
 
     i = ASN1_item_i2d(x, &b, it);
     if (b == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         return NULL;
     }
     p = b;

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

@@ -42,10 +42,8 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, const void *x)
         return 0;
 
     b = OPENSSL_malloc(n);
-    if (b == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (b == NULL)
         return 0;
-    }
 
     p = (unsigned char *)b;
     i2d(x, &p);
@@ -91,7 +89,7 @@ int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, const void *x)
 
     n = ASN1_item_i2d(x, &b, it);
     if (b == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         return 0;
     }
 

+ 9 - 11
libs/openssl/crypto/asn1/a_int.c

@@ -303,8 +303,10 @@ ASN1_INTEGER *ossl_c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
     } else
         ret = *a;
 
-    if (ASN1_STRING_set(ret, NULL, r) == 0)
+    if (ASN1_STRING_set(ret, NULL, r) == 0) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         goto err;
+    }
 
     c2i_ibuf(ret->data, &neg, *pp, len);
 
@@ -318,7 +320,6 @@ ASN1_INTEGER *ossl_c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
         (*a) = ret;
     return ret;
  err:
-    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
     if (a == NULL || *a != ret)
         ASN1_INTEGER_free(ret);
     return NULL;
@@ -400,7 +401,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
     unsigned char *s;
     long len = 0;
     int inf, tag, xclass;
-    int i;
+    int i = 0;
 
     if ((a == NULL) || ((*a) == NULL)) {
         if ((ret = ASN1_INTEGER_new()) == NULL)
@@ -430,10 +431,8 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
      * a missing NULL parameter.
      */
     s = OPENSSL_malloc((int)len + 1);
-    if (s == NULL) {
-        i = ERR_R_MALLOC_FAILURE;
+    if (s == NULL)
         goto err;
-    }
     ret->type = V_ASN1_INTEGER;
     if (len) {
         if ((*p == 0) && (len != 1)) {
@@ -444,15 +443,14 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
         p += len;
     }
 
-    OPENSSL_free(ret->data);
-    ret->data = s;
-    ret->length = (int)len;
+    ASN1_STRING_set0(ret, s, (int)len);
     if (a != NULL)
         (*a) = ret;
     *pp = p;
     return ret;
  err:
-    ERR_raise(ERR_LIB_ASN1, i);
+    if (i != 0)
+        ERR_raise(ERR_LIB_ASN1, i);
     if ((a == NULL) || (*a != ret))
         ASN1_INTEGER_free(ret);
     return NULL;
@@ -485,7 +483,7 @@ static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
         len = 1;
 
     if (ASN1_STRING_set(ret, NULL, len) == 0) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         goto err;
     }
 

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

@@ -139,15 +139,13 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
     if (*out) {
         free_out = 0;
         dest = *out;
-        OPENSSL_free(dest->data);
-        dest->data = NULL;
-        dest->length = 0;
+        ASN1_STRING_set0(dest,  NULL, 0);
         dest->type = str_type;
     } else {
         free_out = 1;
         dest = ASN1_STRING_type_new(str_type);
         if (dest == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
             return -1;
         }
         *out = dest;
@@ -155,7 +153,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
     /* If both the same type just copy across */
     if (inform == outform) {
         if (!ASN1_STRING_set(dest, in, len)) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
             return -1;
         }
         return str_type;
@@ -187,7 +185,6 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
     if ((p = OPENSSL_malloc(outlen + 1)) == NULL) {
         if (free_out)
             ASN1_STRING_free(dest);
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
         return -1;
     }
     dest->length = outlen;

+ 5 - 15
libs/openssl/crypto/asn1/a_object.c

@@ -31,10 +31,8 @@ int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
         return objsize;
 
     if (*pp == NULL) {
-        if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        if ((p = allocated = OPENSSL_malloc(objsize)) == NULL)
             return 0;
-        }
     } else {
         p = *pp;
     }
@@ -135,10 +133,8 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
                     OPENSSL_free(tmp);
                 tmpsize = blsize + 32;
                 tmp = OPENSSL_malloc(tmpsize);
-                if (tmp == NULL) {
-                    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+                if (tmp == NULL)
                     goto err;
-                }
             }
             while (blsize--) {
                 BN_ULONG t = BN_div_word(bl, 0x80L);
@@ -196,10 +192,8 @@ int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
             ERR_raise(ERR_LIB_ASN1, ASN1_R_LENGTH_TOO_LONG);
             return -1;
         }
-        if ((p = OPENSSL_malloc(i + 1)) == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        if ((p = OPENSSL_malloc(i + 1)) == NULL)
             return -1;
-        }
         i2t_ASN1_OBJECT(p, i + 1, a);
     }
     if (i <= 0) {
@@ -308,10 +302,8 @@ ASN1_OBJECT *ossl_c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
         ret->length = 0;
         OPENSSL_free(data);
         data = OPENSSL_malloc(length);
-        if (data == NULL) {
-            i = ERR_R_MALLOC_FAILURE;
+        if (data == NULL)
             goto err;
-        }
         ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
     }
     memcpy(data, p, length);
@@ -345,10 +337,8 @@ ASN1_OBJECT *ASN1_OBJECT_new(void)
     ASN1_OBJECT *ret;
 
     ret = OPENSSL_zalloc(sizeof(*ret));
-    if (ret == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (ret == NULL)
         return NULL;
-    }
     ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
     return ret;
 }

+ 15 - 25
libs/openssl/crypto/asn1/a_sign.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 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,7 +35,7 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
     X509_ALGOR *a;
 
     if (ctx == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB);
         goto err;
     }
     for (i = 0; i < 2; i++) {
@@ -82,7 +82,6 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
     buf_out = OPENSSL_malloc(outll);
     if (buf_in == NULL || buf_out == NULL) {
         outl = 0;
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     p = buf_in;
@@ -96,16 +95,13 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
         ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB);
         goto err;
     }
-    OPENSSL_free(signature->data);
-    signature->data = buf_out;
+    ASN1_STRING_set0(signature, buf_out, outl);
     buf_out = NULL;
-    signature->length = outl;
     /*
      * In the interests of compatibility, I'll make sure that the bit string
      * has a 'not-used bits' value of 0
      */
-    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+    ossl_asn1_string_set_bits_left(signature, 0);
  err:
     EVP_MD_CTX_free(ctx);
     OPENSSL_clear_free((char *)buf_in, inll);
@@ -133,7 +129,7 @@ int ASN1_item_sign_ex(const ASN1_ITEM *it, X509_ALGOR *algor1,
     EVP_MD_CTX *ctx = evp_md_ctx_new_ex(pkey, id, libctx, propq);
 
     if (ctx == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB);
         return 0;
     }
     /* We can use the non _ex variant here since the pkey is already setup */
@@ -247,16 +243,14 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
             goto err;
         }
 
-        if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
-            paramtype = V_ASN1_NULL;
-        else
-            paramtype = V_ASN1_UNDEF;
-
-        if (algor1)
-            X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
-        if (algor2)
-            X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
-
+        paramtype = pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL ?
+            V_ASN1_NULL : V_ASN1_UNDEF;
+        if (algor1 != NULL
+            && !X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL))
+            goto err;
+        if (algor2 != NULL
+            && !X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL))
+            goto err;
     }
 
     buf_len = ASN1_item_i2d(data, &buf_in, it);
@@ -275,7 +269,6 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
     buf_out = OPENSSL_malloc(outll);
     if (buf_in == NULL || buf_out == NULL) {
         outl = 0;
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
@@ -284,16 +277,13 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
         ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB);
         goto err;
     }
-    OPENSSL_free(signature->data);
-    signature->data = buf_out;
+    ASN1_STRING_set0(signature, buf_out, outl);
     buf_out = NULL;
-    signature->length = outl;
     /*
      * In the interests of compatibility, I'll make sure that the bit string
      * has a 'not-used bits' value of 0
      */
-    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+    ossl_asn1_string_set_bits_left(signature, 0);
  err:
     OPENSSL_clear_free((char *)buf_in, inl);
     OPENSSL_clear_free((char *)buf_out, outll);

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

@@ -282,10 +282,8 @@ static int do_dump(unsigned long lflags, char_io *io_ch, void *arg,
     der_len = i2d_ASN1_TYPE(&t, NULL);
     if (der_len <= 0)
         return -1;
-    if ((der_buf = OPENSSL_malloc(der_len)) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if ((der_buf = OPENSSL_malloc(der_len)) == NULL)
         return -1;
-    }
     p = der_buf;
     i2d_ASN1_TYPE(&t, &p);
     outlen = do_hex_dump(io_ch, arg, der_buf, der_len);

+ 8 - 8
libs/openssl/crypto/asn1/a_strnid.c

@@ -50,10 +50,10 @@ int ASN1_STRING_set_default_mask_asc(const char *p)
     unsigned long mask;
     char *end;
 
-    if (strncmp(p, "MASK:", 5) == 0) {
-        if (p[5] == '\0')
+    if (CHECK_AND_SKIP_PREFIX(p, "MASK:")) {
+        if (*p == '\0')
             return 0;
-        mask = strtoul(p + 5, &end, 0);
+        mask = strtoul(p, &end, 0);
         if (*end)
             return 0;
     } else if (strcmp(p, "nombstr") == 0)
@@ -135,7 +135,9 @@ ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
 #endif
 
     fnd.nid = nid;
-    if (stable) {
+    if (stable != NULL) {
+        /* Ideally, this would be done under lock */
+        sk_ASN1_STRING_TABLE_sort(stable);
         idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
         if (idx >= 0)
             return sk_ASN1_STRING_TABLE_value(stable, idx);
@@ -161,10 +163,8 @@ static ASN1_STRING_TABLE *stable_get(int nid)
     tmp = ASN1_STRING_TABLE_get(nid);
     if (tmp != NULL && tmp->flags & STABLE_FLAGS_MALLOC)
         return tmp;
-    if ((rv = OPENSSL_zalloc(sizeof(*rv))) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if ((rv = OPENSSL_zalloc(sizeof(*rv))) == NULL)
         return NULL;
-    }
     if (!sk_ASN1_STRING_TABLE_push(stable, rv)) {
         OPENSSL_free(rv);
         return NULL;
@@ -192,7 +192,7 @@ int ASN1_STRING_TABLE_add(int nid,
 
     tmp = stable_get(nid);
     if (tmp == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         return 0;
     }
     if (minsize >= 0)

+ 78 - 5
libs/openssl/crypto/asn1/a_time.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 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
@@ -420,10 +420,8 @@ int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str)
              * new t.data would be freed after ASN1_STRING_copy is done.
              */
             t.data = OPENSSL_zalloc(t.length + 1);
-            if (t.data == NULL) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            if (t.data == NULL)
                 goto out;
-            }
             memcpy(t.data, str + 2, t.length);
             t.type = V_ASN1_UTCTIME;
         }
@@ -571,7 +569,7 @@ int ASN1_TIME_normalize(ASN1_TIME *t)
 {
     struct tm tm;
 
-    if (!ASN1_TIME_to_tm(t, &tm))
+    if (t == NULL || !ASN1_TIME_to_tm(t, &tm))
         return 0;
 
     return ossl_asn1_time_from_tm(t, &tm, V_ASN1_UNDEF) != NULL;
@@ -589,3 +587,78 @@ 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;
+}

+ 7 - 8
libs/openssl/crypto/asn1/a_verify.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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
@@ -33,7 +33,7 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
     int ret = -1, i, inl;
 
     if (ctx == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB);
         goto err;
     }
     i = OBJ_obj2nid(a->algorithm);
@@ -54,10 +54,8 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
         goto err;
     }
     buf_in = OPENSSL_malloc((unsigned int)inl);
-    if (buf_in == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (buf_in == NULL)
         goto err;
-    }
     p = buf_in;
 
     i2d(data, &p);
@@ -182,8 +180,9 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
             if (mdnid != NID_undef) {
                 type = EVP_get_digestbynid(mdnid);
                 if (type == NULL) {
-                    ERR_raise(ERR_LIB_ASN1,
-                              ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+                    ERR_raise_data(ERR_LIB_ASN1,
+                                   ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM,
+                                   "nid=0x%x", mdnid);
                     goto err;
                 }
             }
@@ -206,7 +205,7 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
         goto err;
     }
     if (buf_in == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         goto err;
     }
     inll = inl;

+ 1 - 4
libs/openssl/crypto/asn1/ameth_lib.c

@@ -222,10 +222,8 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
 {
     EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth));
 
-    if (ameth == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (ameth == NULL)
         return NULL;
-    }
 
     ameth->pkey_id = id;
     ameth->pkey_base_id = id;
@@ -247,7 +245,6 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
 
  err:
     EVP_PKEY_asn1_free(ameth);
-    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
     return NULL;
 }
 

+ 16 - 18
libs/openssl/crypto/asn1/asn1_gen.c

@@ -7,9 +7,10 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "internal/cryptlib.h"
 #include <openssl/asn1.h>
 #include <openssl/x509v3.h>
+#include "internal/cryptlib.h"
+#include "crypto/asn1.h"
 
 #define ASN1_GEN_FLAG           0x10000
 #define ASN1_GEN_FLAG_IMP       (ASN1_GEN_FLAG|1)
@@ -324,13 +325,13 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
             ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT);
             return -1;
         }
-        if (strncmp(vstart, "ASCII", 5) == 0)
+        if (HAS_PREFIX(vstart, "ASCII"))
             arg->format = ASN1_GEN_FORMAT_ASCII;
-        else if (strncmp(vstart, "UTF8", 4) == 0)
+        else if (HAS_PREFIX(vstart, "UTF8"))
             arg->format = ASN1_GEN_FORMAT_UTF8;
-        else if (strncmp(vstart, "HEX", 3) == 0)
+        else if (HAS_PREFIX(vstart, "HEX"))
             arg->format = ASN1_GEN_FORMAT_HEX;
-        else if (strncmp(vstart, "BITLIST", 7) == 0)
+        else if (HAS_PREFIX(vstart, "BITLIST"))
             arg->format = ASN1_GEN_FORMAT_BITLIST;
         else {
             ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT);
@@ -581,7 +582,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
     int no_unused = 1;
 
     if ((atmp = ASN1_TYPE_new()) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         return NULL;
     }
 
@@ -642,11 +643,11 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
             goto bad_form;
         }
         if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
             goto bad_str;
         }
         if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
             goto bad_str;
         }
         atmp->value.asn1_string->type = utype;
@@ -677,7 +678,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
 
         if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
                                -1, format, ASN1_tag2bit(utype)) <= 0) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
             goto bad_str;
         }
 
@@ -686,7 +687,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
     case V_ASN1_BIT_STRING:
     case V_ASN1_OCTET_STRING:
         if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
             goto bad_form;
         }
 
@@ -700,7 +701,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
             atmp->value.asn1_string->type = utype;
         } else if (format == ASN1_GEN_FORMAT_ASCII) {
             if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+                ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
                 goto bad_str;
             }
         } else if ((format == ASN1_GEN_FORMAT_BITLIST)
@@ -717,11 +718,8 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
             goto bad_form;
         }
 
-        if ((utype == V_ASN1_BIT_STRING) && no_unused) {
-            atmp->value.asn1_string->flags
-                &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-            atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-        }
+        if ((utype == V_ASN1_BIT_STRING) && no_unused)
+            ossl_asn1_string_set_bits_left(atmp->value.asn1_string, 0);
 
         break;
 
@@ -756,7 +754,7 @@ static int bitstr_cb(const char *elem, int len, void *bitstr)
         return 0;
     }
     if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         return 0;
     }
     return 1;
@@ -768,7 +766,7 @@ static int mask_cb(const char *elem, int len, void *arg)
     int tag;
     if (elem == NULL)
         return 0;
-    if ((len == 3) && (strncmp(elem, "DIR", 3) == 0)) {
+    if (len == 3 && HAS_PREFIX(elem, "DIR")) {
         *pmask |= B_ASN1_DIRECTORYSTRING;
         return 1;
     }

+ 7 - 4
libs/openssl/crypto/asn1/asn1_lib.c

@@ -248,6 +248,12 @@ int ASN1_object_size(int constructed, int length, int tag)
     return ret + length;
 }
 
+void ossl_asn1_string_set_bits_left(ASN1_STRING *str, unsigned int num)
+{
+    str->flags &= ~0x07;
+    str->flags |= ASN1_STRING_FLAG_BITS_LEFT | (num & 0x07);
+}
+
 int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
 {
     if (str == NULL)
@@ -308,7 +314,6 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in)
         str->data = OPENSSL_realloc(c, len + 1);
 #endif
         if (str->data == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
             str->data = c;
             return 0;
         }
@@ -348,10 +353,8 @@ ASN1_STRING *ASN1_STRING_type_new(int type)
     ASN1_STRING *ret;
 
     ret = OPENSSL_zalloc(sizeof(*ret));
-    if (ret == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (ret == NULL)
         return NULL;
-    }
     ret->type = type;
     return ret;
 }

+ 2 - 0
libs/openssl/crypto/asn1/asn1_local.h

@@ -9,6 +9,8 @@
 
 /* Internal ASN1 structures and functions: not for application use */
 
+#include "crypto/asn1.h"
+
 typedef const ASN1_VALUE const_ASN1_VALUE;
 SKM_DEFINE_STACK_OF(const_ASN1_VALUE, const ASN1_VALUE, ASN1_VALUE)
 

+ 13 - 12
libs/openssl/crypto/asn1/asn_mime.c

@@ -76,7 +76,7 @@ int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
         BIO *bio, *tbio;
         bio = BIO_new_NDEF(out, val, it);
         if (!bio) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB);
             return 0;
         }
         if (!SMIME_crlf_copy(in, bio, flags)) {
@@ -109,7 +109,7 @@ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
     int r;
     b64 = BIO_new(BIO_f_base64());
     if (b64 == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_BIO_LIB);
         return 0;
     }
     /*
@@ -142,7 +142,7 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it, ASN1_VALUE **x,
     ASN1_VALUE *val;
 
     if ((b64 = BIO_new(BIO_f_base64())) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_BIO_LIB);
         return 0;
     }
     bio = BIO_push(b64, bio);
@@ -528,7 +528,7 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
      */
     bf = BIO_new(BIO_f_buffer());
     if (bf == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_BIO_LIB);
         return 0;
     }
     out = BIO_push(bf, out);
@@ -685,7 +685,7 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
     char linebuf[MAX_SMLEN];
     MIME_HEADER *mhdr = NULL, *new_hdr = NULL;
     STACK_OF(MIME_HEADER) *headers;
-    int len, state, save_state = 0;
+    int i, len, state, save_state = 0;
 
     headers = sk_MIME_HEADER_new(mime_hdr_cmp);
     if (headers == NULL)
@@ -791,6 +791,12 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
             break;              /* Blank line means end of headers */
     }
 
+    /* Sort the headers and their params for faster searching */
+    sk_MIME_HEADER_sort(headers);
+    for (i = 0; i < sk_MIME_HEADER_num(headers); i++)
+        if ((mhdr = sk_MIME_HEADER_value(headers, i)) != NULL
+                && mhdr->params != NULL)
+            sk_MIME_PARAM_sort(mhdr->params);
     return headers;
 
  err:
@@ -989,13 +995,8 @@ static int mime_bound_check(char *line, int linelen, const char *bound, int blen
     if (blen + 2 > linelen)
         return 0;
     /* Check for part boundary */
-    if ((strncmp(line, "--", 2) == 0)
-        && strncmp(line + 2, bound, blen) == 0) {
-        if (strncmp(line + blen + 2, "--", 2) == 0)
-            return 2;
-        else
-            return 1;
-    }
+    if ((CHECK_AND_SKIP_PREFIX(line, "--")) && strncmp(line, bound, blen) == 0)
+        return HAS_PREFIX(line + blen, "--") ? 2 : 1;
     return 0;
 }
 

+ 1 - 3
libs/openssl/crypto/asn1/asn_moid.c

@@ -83,10 +83,8 @@ static int do_create(const char *value, const char *name)
             p--;
         }
         p++;
-        if ((lntmp = OPENSSL_malloc((p - ln) + 1)) == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        if ((lntmp = OPENSSL_malloc((p - ln) + 1)) == NULL)
             return 0;
-        }
         memcpy(lntmp, ln, p - ln);
         lntmp[p - ln] = '\0';
         ln = lntmp;

+ 1 - 1
libs/openssl/crypto/asn1/asn_mstbl.c

@@ -106,7 +106,7 @@ static int do_tcreate(const char *value, const char *name)
         rv = ASN1_STRING_TABLE_add(nid, tbl_min, tbl_max,
                                    tbl_mask, tbl_flags);
         if (!rv)
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
     }
     sk_CONF_VALUE_pop_free(lst, X509V3_conf_free);
     return rv;

+ 17 - 5
libs/openssl/crypto/asn1/asn_pack.c

@@ -17,24 +17,23 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
 {
     ASN1_STRING *octmp;
 
-     if (oct == NULL || *oct == NULL) {
+    if (oct == NULL || *oct == NULL) {
         if ((octmp = ASN1_STRING_new()) == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
             return NULL;
         }
     } else {
         octmp = *oct;
     }
 
-    OPENSSL_free(octmp->data);
-    octmp->data = NULL;
+    ASN1_STRING_set0(octmp, NULL, 0);
 
     if ((octmp->length = ASN1_item_i2d(obj, &octmp->data, it)) <= 0) {
         ERR_raise(ERR_LIB_ASN1, ASN1_R_ENCODE_ERROR);
         goto err;
     }
     if (octmp->data == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         goto err;
     }
 
@@ -60,3 +59,16 @@ void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it)
         ERR_raise(ERR_LIB_ASN1, ASN1_R_DECODE_ERROR);
     return ret;
 }
+
+void *ASN1_item_unpack_ex(const ASN1_STRING *oct, const ASN1_ITEM *it,
+                          OSSL_LIB_CTX *libctx, const char *propq)
+{
+    const unsigned char *p;
+    void *ret;
+
+    p = oct->data;
+    if ((ret = ASN1_item_d2i_ex(NULL, &p, oct->length, it,\
+                                libctx, propq)) == NULL)
+        ERR_raise(ERR_LIB_ASN1, ASN1_R_DECODE_ERROR);
+    return ret;
+}

+ 5 - 5
libs/openssl/crypto/asn1/bio_asn1.c

@@ -100,10 +100,8 @@ static int asn1_bio_new(BIO *b)
 {
     BIO_ASN1_BUF_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
 
-    if (ctx == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (ctx == NULL)
         return 0;
-    }
     if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
         OPENSSL_free(ctx);
         return 0;
@@ -116,10 +114,12 @@ static int asn1_bio_new(BIO *b)
 
 static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
 {
-    if (size <= 0 || (ctx->buf = OPENSSL_malloc(size)) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (size <= 0) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_INVALID_ARGUMENT);
         return 0;
     }
+    if ((ctx->buf = OPENSSL_malloc(size)) == NULL)
+        return 0;
     ctx->bufsize = size;
     ctx->asn1_class = V_ASN1_UNIVERSAL;
     ctx->asn1_tag = V_ASN1_OCTET_STRING;

+ 2 - 6
libs/openssl/crypto/asn1/bio_ndef.c

@@ -140,10 +140,8 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
     derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
     if (derlen < 0)
         return 0;
-    if ((p = OPENSSL_malloc(derlen)) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if ((p = OPENSSL_malloc(derlen)) == NULL)
         return 0;
-    }
 
     ndef_aux->derbuf = p;
     *pbuf = p;
@@ -215,10 +213,8 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
     derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
     if (derlen < 0)
         return 0;
-    if ((p = OPENSSL_malloc(derlen)) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if ((p = OPENSSL_malloc(derlen)) == NULL)
         return 0;
-    }
 
     ndef_aux->derbuf = p;
     *pbuf = p;

+ 0 - 1
libs/openssl/crypto/asn1/f_int.c

@@ -108,7 +108,6 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
         if (num + i > slen) {
             sp = OPENSSL_clear_realloc(s, slen, num + i * 2);
             if (sp == NULL) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
                 OPENSSL_free(s);
                 return 0;
             }

+ 0 - 1
libs/openssl/crypto/asn1/f_string.c

@@ -99,7 +99,6 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
         if (num + i > slen) {
             sp = OPENSSL_realloc(s, (unsigned int)num + i * 2);
             if (sp == NULL) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
                 OPENSSL_free(s);
                 return 0;
             }

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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
@@ -34,7 +34,6 @@ static int i2d_provided(const EVP_PKEY *a, int selection,
                         const struct type_and_structure_st *output_info,
                         unsigned char **pp)
 {
-    OSSL_ENCODER_CTX *ctx = NULL;
     int ret;
 
     for (ret = -1;
@@ -49,6 +48,7 @@ static int i2d_provided(const EVP_PKEY *a, int selection,
          */
         size_t len = INT_MAX;
         int pp_was_NULL = (pp == NULL || *pp == NULL);
+        OSSL_ENCODER_CTX *ctx;
 
         ctx = OSSL_ENCODER_CTX_new_for_pkey(a, selection,
                                             output_info->output_type,
@@ -63,7 +63,6 @@ static int i2d_provided(const EVP_PKEY *a, int selection,
                 ret = INT_MAX - (int)len;
         }
         OSSL_ENCODER_CTX_free(ctx);
-        ctx = NULL;
     }
 
     if (ret == -1)

+ 9 - 9
libs/openssl/crypto/asn1/p5_pbe.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 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/asn1t.h>
 #include <openssl/x509.h>
 #include <openssl/rand.h>
+#include "crypto/evp.h"
 
 /* PKCS#5 password based encryption structure */
 
@@ -34,25 +35,24 @@ int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter,
 
     pbe = PBEPARAM_new();
     if (pbe == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        /* ERR_R_ASN1_LIB, because PBEPARAM_new() is defined in crypto/asn1 */
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         goto err;
     }
     if (iter <= 0)
         iter = PKCS5_DEFAULT_ITER;
     if (!ASN1_INTEGER_set(pbe->iter, iter)) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         goto err;
     }
     if (!saltlen)
-        saltlen = PKCS5_SALT_LEN;
+        saltlen = PKCS5_DEFAULT_PBE1_SALT_LEN;
     if (saltlen < 0)
         goto err;
 
     sstr = OPENSSL_malloc(saltlen);
-    if (sstr == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (sstr == NULL)
         goto err;
-    }
     if (salt)
         memcpy(sstr, salt, saltlen);
     else if (RAND_bytes_ex(ctx, sstr, saltlen, 0) <= 0)
@@ -62,7 +62,7 @@ int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter,
     sstr = NULL;
 
     if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         goto err;
     }
 
@@ -94,7 +94,7 @@ X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter,
     X509_ALGOR *ret;
     ret = X509_ALGOR_new();
     if (ret == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB);
         return NULL;
     }
 

+ 73 - 43
libs/openssl/crypto/asn1/p5_pbev2.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 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,8 @@
 
 #include <stdio.h>
 #include "internal/cryptlib.h"
+#include "crypto/asn1.h"
+#include "crypto/evp.h"
 #include <openssl/asn1t.h>
 #include <openssl/core.h>
 #include <openssl/core_names.h>
@@ -56,14 +58,18 @@ X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter,
         goto err;
     }
 
-    if ((pbe2 = PBE2PARAM_new()) == NULL)
-        goto merr;
+    if ((pbe2 = PBE2PARAM_new()) == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     /* Setup the AlgorithmIdentifier for the encryption scheme */
     scheme = pbe2->encryption;
     scheme->algorithm = OBJ_nid2obj(alg_nid);
-    if ((scheme->parameter = ASN1_TYPE_new()) == NULL)
-        goto merr;
+    if ((scheme->parameter = ASN1_TYPE_new()) == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     /* Create random IV */
     ivlen = EVP_CIPHER_get_iv_length(cipher);
@@ -75,8 +81,10 @@ X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter,
     }
 
     ctx = EVP_CIPHER_CTX_new();
-    if (ctx == NULL)
-        goto merr;
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB);
+        goto err;
+    }
 
     /* Dummy cipherinit to just setup the IV, and PRF */
     if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0))
@@ -112,30 +120,33 @@ X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter,
     pbe2->keyfunc = PKCS5_pbkdf2_set_ex(iter, salt, saltlen, prf_nid, keylen,
                                         libctx);
 
-    if (pbe2->keyfunc == NULL)
-        goto merr;
+    if (pbe2->keyfunc == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     /* Now set up top level AlgorithmIdentifier */
 
-    if ((ret = X509_ALGOR_new()) == NULL)
-        goto merr;
+    if ((ret = X509_ALGOR_new()) == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB);
+        goto err;
+    }
 
     ret->algorithm = OBJ_nid2obj(NID_pbes2);
 
     /* Encode PBE2PARAM into parameter */
 
     if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
-                                 &ret->parameter))
-         goto merr;
+                                 &ret->parameter)) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     PBE2PARAM_free(pbe2);
     pbe2 = NULL;
 
     return ret;
 
- merr:
-    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
-
  err:
     EVP_CIPHER_CTX_free(ctx);
     PBE2PARAM_free(pbe2);
@@ -169,70 +180,89 @@ X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen,
     PBKDF2PARAM *kdf = NULL;
     ASN1_OCTET_STRING *osalt = NULL;
 
-    if ((kdf = PBKDF2PARAM_new()) == NULL)
-        goto merr;
-    if ((osalt = ASN1_OCTET_STRING_new()) == NULL)
-        goto merr;
+    if ((kdf = PBKDF2PARAM_new()) == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
+    if ((osalt = ASN1_OCTET_STRING_new()) == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     kdf->salt->value.octet_string = osalt;
     kdf->salt->type = V_ASN1_OCTET_STRING;
 
-    if (saltlen < 0)
-        goto merr;
+    if (saltlen < 0) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_INVALID_ARGUMENT);
+        goto err;
+    }
     if (saltlen == 0)
-        saltlen = PKCS5_SALT_LEN;
+        saltlen = PKCS5_DEFAULT_PBE2_SALT_LEN;
     if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL)
-        goto merr;
+        goto err;
+
 
     osalt->length = saltlen;
 
-    if (salt)
+    if (salt) {
         memcpy(osalt->data, salt, saltlen);
-    else if (RAND_bytes_ex(libctx, osalt->data, saltlen, 0) <= 0)
-        goto merr;
+    } else if (RAND_bytes_ex(libctx, osalt->data, saltlen, 0) <= 0) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_RAND_LIB);
+        goto err;
+    }
 
     if (iter <= 0)
         iter = PKCS5_DEFAULT_ITER;
 
-    if (!ASN1_INTEGER_set(kdf->iter, iter))
-        goto merr;
+    if (!ASN1_INTEGER_set(kdf->iter, iter)) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     /* If have a key len set it up */
 
     if (keylen > 0) {
-        if ((kdf->keylength = ASN1_INTEGER_new()) == NULL)
-            goto merr;
-        if (!ASN1_INTEGER_set(kdf->keylength, keylen))
-            goto merr;
+        if ((kdf->keylength = ASN1_INTEGER_new()) == NULL) {
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        if (!ASN1_INTEGER_set(kdf->keylength, keylen)) {
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+            goto err;
+        }
     }
 
     /* prf can stay NULL if we are using hmacWithSHA1 */
     if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
-        kdf->prf = X509_ALGOR_new();
-        if (kdf->prf == NULL)
-            goto merr;
-        X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
+        kdf->prf = ossl_X509_ALGOR_from_nid(prf_nid, V_ASN1_NULL, NULL);
+        if (kdf->prf == NULL) {
+            ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB);
+            goto err;
+        }
     }
 
     /* Finally setup the keyfunc structure */
 
     keyfunc = X509_ALGOR_new();
-    if (keyfunc == NULL)
-        goto merr;
+    if (keyfunc == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB);
+        goto err;
+    }
 
     keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
 
     /* Encode PBKDF2PARAM into parameter of pbe2 */
 
     if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), kdf,
-                                 &keyfunc->parameter))
-         goto merr;
+                                 &keyfunc->parameter)) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     PBKDF2PARAM_free(kdf);
     return keyfunc;
 
- merr:
-    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+ err:
     PBKDF2PARAM_free(kdf);
     X509_ALGOR_free(keyfunc);
     return NULL;

+ 62 - 37
libs/openssl/crypto/asn1/p5_scrypt.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2023 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
@@ -67,16 +67,20 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
     }
 
     pbe2 = PBE2PARAM_new();
-    if (pbe2 == NULL)
-        goto merr;
+    if (pbe2 == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     /* Setup the AlgorithmIdentifier for the encryption scheme */
     scheme = pbe2->encryption;
 
     scheme->algorithm = OBJ_nid2obj(alg_nid);
     scheme->parameter = ASN1_TYPE_new();
-    if (scheme->parameter == NULL)
-        goto merr;
+    if (scheme->parameter == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     /* Create random IV */
     if (EVP_CIPHER_get_iv_length(cipher)) {
@@ -87,8 +91,10 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
     }
 
     ctx = EVP_CIPHER_CTX_new();
-    if (ctx == NULL)
-        goto merr;
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB);
+        goto err;
+    }
 
     /* Dummy cipherinit to just setup the IV */
     if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0)
@@ -111,31 +117,34 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
 
     pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p);
 
-    if (pbe2->keyfunc == NULL)
-        goto merr;
+    if (pbe2->keyfunc == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     /* Now set up top level AlgorithmIdentifier */
 
     ret = X509_ALGOR_new();
-    if (ret == NULL)
-        goto merr;
+    if (ret == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     ret->algorithm = OBJ_nid2obj(NID_pbes2);
 
     /* Encode PBE2PARAM into parameter */
 
     if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
-                                &ret->parameter) == NULL)
-        goto merr;
+                                &ret->parameter) == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     PBE2PARAM_free(pbe2);
     pbe2 = NULL;
 
     return ret;
 
- merr:
-    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
-
  err:
     PBE2PARAM_free(pbe2);
     X509_ALGOR_free(ret);
@@ -151,57 +160,73 @@ static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
     X509_ALGOR *keyfunc = NULL;
     SCRYPT_PARAMS *sparam = SCRYPT_PARAMS_new();
 
-    if (sparam == NULL)
-        goto merr;
+    if (sparam == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     if (!saltlen)
-        saltlen = PKCS5_SALT_LEN;
+        saltlen = PKCS5_DEFAULT_PBE2_SALT_LEN;
 
     /* This will either copy salt or grow the buffer */
-    if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0)
-        goto merr;
+    if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0)
         goto err;
 
-    if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0)
-        goto merr;
+    if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
-    if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0)
-        goto merr;
+    if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
-    if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0)
-        goto merr;
+    if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     /* If have a key len set it up */
 
     if (keylen > 0) {
         sparam->keyLength = ASN1_INTEGER_new();
-        if (sparam->keyLength == NULL)
-            goto merr;
-        if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0)
-            goto merr;
+        if (sparam->keyLength == NULL) {
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0) {
+            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+            goto err;
+        }
     }
 
     /* Finally setup the keyfunc structure */
 
     keyfunc = X509_ALGOR_new();
-    if (keyfunc == NULL)
-        goto merr;
+    if (keyfunc == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt);
 
     /* Encode SCRYPT_PARAMS into parameter of pbe2 */
 
     if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam,
-                                &keyfunc->parameter) == NULL)
-        goto merr;
+                                &keyfunc->parameter) == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     SCRYPT_PARAMS_free(sparam);
     return keyfunc;
 
- merr:
-    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
  err:
     SCRYPT_PARAMS_free(sparam);
     X509_ALGOR_free(keyfunc);

+ 2 - 4
libs/openssl/crypto/asn1/standard_methods.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2023 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
@@ -32,11 +32,9 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
 #ifndef OPENSSL_NO_DH
     &ossl_dhx_asn1_meth,
 #endif
-#ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_ECX
     &ossl_ecx25519_asn1_meth,
     &ossl_ecx448_asn1_meth,
-#endif
-#ifndef OPENSSL_NO_EC
     &ossl_ed25519_asn1_meth,
     &ossl_ed448_asn1_meth,
 #endif

+ 7 - 9
libs/openssl/crypto/asn1/tasn_dec.c

@@ -629,7 +629,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
         }
 
         if (*val == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB);
             goto err;
         }
 
@@ -658,7 +658,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
             }
             len -= p - q;
             if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+                ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB);
                 ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item));
                 goto err;
             }
@@ -802,7 +802,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
         len = buf.length;
         /* Append a final null to string */
         if (!BUF_MEM_grow_clean(&buf, len + 1)) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB);
             goto err;
         }
         buf.data[len] = 0;
@@ -925,7 +925,7 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
         if (*pval == NULL) {
             stmp = ASN1_STRING_type_new(utype);
             if (stmp == NULL) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+                ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
                 goto err;
             }
             *pval = (ASN1_VALUE *)stmp;
@@ -935,13 +935,11 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
         }
         /* If we've already allocated a buffer use it */
         if (*free_cont) {
-            OPENSSL_free(stmp->data);
-            stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
-            stmp->length = len;
+            ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, len);
             *free_cont = 0;
         } else {
             if (!ASN1_STRING_set(stmp, cont, len)) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+                ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
                 ASN1_STRING_free(stmp);
                 *pval = NULL;
                 goto err;
@@ -1100,7 +1098,7 @@ static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
     if (buf) {
         len = buf->length;
         if (!BUF_MEM_grow_clean(buf, len + plen)) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB);
             return 0;
         }
         memcpy(buf->data + len, *p, plen);

+ 3 - 9
libs/openssl/crypto/asn1/tasn_enc.c

@@ -62,10 +62,8 @@ static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out,
         len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
         if (len <= 0)
             return len;
-        if ((buf = OPENSSL_malloc(len)) == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        if ((buf = OPENSSL_malloc(len)) == NULL)
             return -1;
-        }
         p = buf;
         ASN1_item_ex_i2d(&val, &p, it, -1, flags);
         *out = buf;
@@ -415,15 +413,11 @@ static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE) *sk,
         else {
             derlst = OPENSSL_malloc(sk_const_ASN1_VALUE_num(sk)
                                     * sizeof(*derlst));
-            if (derlst == NULL) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            if (derlst == NULL)
                 return 0;
-            }
             tmpdat = OPENSSL_malloc(skcontlen);
-            if (tmpdat == NULL) {
-                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            if (tmpdat == NULL)
                 goto err;
-            }
         }
     }
     /* If not sorting just output each item */

+ 14 - 16
libs/openssl/crypto/asn1/tasn_new.c

@@ -78,10 +78,10 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed,
         if (ef != NULL) {
             if (ef->asn1_ex_new_ex != NULL) {
                 if (!ef->asn1_ex_new_ex(pval, it, libctx, propq))
-                    goto memerr;
+                    goto asn1err;
             } else if (ef->asn1_ex_new != NULL) {
                 if (!ef->asn1_ex_new(pval, it))
-                    goto memerr;
+                    goto asn1err;
             }
         }
         break;
@@ -89,14 +89,14 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed,
     case ASN1_ITYPE_PRIMITIVE:
         if (it->templates) {
             if (!asn1_template_new(pval, it->templates, libctx, propq))
-                goto memerr;
+                goto asn1err;
         } else if (!asn1_primitive_new(pval, it, embed))
-            goto memerr;
+            goto asn1err;
         break;
 
     case ASN1_ITYPE_MSTRING:
         if (!asn1_primitive_new(pval, it, embed))
-            goto memerr;
+            goto asn1err;
         break;
 
     case ASN1_ITYPE_CHOICE:
@@ -113,7 +113,7 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed,
         } else {
             *pval = OPENSSL_zalloc(it->size);
             if (*pval == NULL)
-                goto memerr;
+                return 0;
         }
         ossl_asn1_set_choice_selector(pval, -1, it);
         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
@@ -135,7 +135,7 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed,
         } else {
             *pval = OPENSSL_zalloc(it->size);
             if (*pval == NULL)
-                goto memerr;
+                return 0;
         }
         /* 0 : init. lock */
         if (ossl_asn1_do_lock(pval, 0, it) < 0) {
@@ -143,13 +143,13 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed,
                 OPENSSL_free(*pval);
                 *pval = NULL;
             }
-            goto memerr;
+            goto asn1err;
         }
         ossl_asn1_enc_init(pval, it);
         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
             pseqval = ossl_asn1_get_field_ptr(pval, tt);
             if (!asn1_template_new(pseqval, tt, libctx, propq))
-                goto memerr2;
+                goto asn1err2;
         }
         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
             goto auxerr2;
@@ -157,10 +157,10 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed,
     }
     return 1;
 
- memerr2:
+ asn1err2:
     ossl_asn1_item_embed_free(pval, it, embed);
- memerr:
-    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+ asn1err:
+    ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
     return 0;
 
  auxerr2:
@@ -230,7 +230,7 @@ static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
         STACK_OF(ASN1_VALUE) *skval;
         skval = sk_ASN1_VALUE_new_null();
         if (!skval) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB);
             ret = 0;
             goto done;
         }
@@ -298,10 +298,8 @@ static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
         return 1;
 
     case V_ASN1_ANY:
-        if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL)
             return 0;
-        }
         typ->value.ptr = NULL;
         typ->type = -1;
         *pval = (ASN1_VALUE *)typ;

+ 1 - 3
libs/openssl/crypto/asn1/tasn_prn.c

@@ -37,10 +37,8 @@ ASN1_PCTX *ASN1_PCTX_new(void)
     ASN1_PCTX *ret;
 
     ret = OPENSSL_zalloc(sizeof(*ret));
-    if (ret == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (ret == NULL)
         return NULL;
-    }
     return ret;
 }
 

+ 13 - 11
libs/openssl/crypto/asn1/tasn_utl.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2023 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
@@ -59,7 +59,7 @@ int ossl_asn1_set_choice_selector(ASN1_VALUE **pval, int value,
 /*
  * Do atomic reference counting. The value 'op' decides what to do.
  * If it is +1 then the count is incremented.
- * If |op| is 0, lock is initialised and count is set to 1.
+ * If |op| is 0, count is initialised and set to 1.
  * If |op| is -1, count is decremented and the return value is the current
  * reference count or 0 if no reference count is active.
  * It returns -1 on initialisation error.
@@ -68,8 +68,8 @@ int ossl_asn1_set_choice_selector(ASN1_VALUE **pval, int value,
 int ossl_asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
 {
     const ASN1_AUX *aux;
-    CRYPTO_REF_COUNT *lck;
     CRYPTO_RWLOCK **lock;
+    CRYPTO_REF_COUNT *refcnt;
     int ret = -1;
 
     if ((it->itype != ASN1_ITYPE_SEQUENCE)
@@ -78,30 +78,34 @@ int ossl_asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
     aux = it->funcs;
     if (aux == NULL || (aux->flags & ASN1_AFLG_REFCOUNT) == 0)
         return 0;
-    lck = offset2ptr(*pval, aux->ref_offset);
     lock = offset2ptr(*pval, aux->ref_lock);
+    refcnt = offset2ptr(*pval, aux->ref_offset);
 
     switch (op) {
     case 0:
-        *lck = ret = 1;
+        if (!CRYPTO_NEW_REF(refcnt, 1))
+            return -1;
         *lock = CRYPTO_THREAD_lock_new();
         if (*lock == NULL) {
-            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+            CRYPTO_FREE_REF(refcnt);
+            ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB);
             return -1;
         }
+        ret = 1;
         break;
     case 1:
-        if (!CRYPTO_UP_REF(lck, &ret, *lock))
+        if (!CRYPTO_UP_REF(refcnt, &ret))
             return -1;
         break;
     case -1:
-        if (!CRYPTO_DOWN_REF(lck, &ret, *lock))
+        if (!CRYPTO_DOWN_REF(refcnt, &ret))
             return -1;  /* failed */
         REF_PRINT_EX(it->sname, ret, (void *)it);
         REF_ASSERT_ISNT(ret < 0);
         if (ret == 0) {
             CRYPTO_THREAD_lock_free(*lock);
             *lock = NULL;
+            CRYPTO_FREE_REF(refcnt);
         }
         break;
     }
@@ -168,10 +172,8 @@ int ossl_asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
     OPENSSL_free(enc->enc);
     if (inlen <= 0)
         return 0;
-    if ((enc->enc = OPENSSL_malloc(inlen)) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if ((enc->enc = OPENSSL_malloc(inlen)) == NULL)
         return 0;
-    }
     memcpy(enc->enc, in, inlen);
     enc->len = inlen;
     enc->modified = 0;

+ 34 - 25
libs/openssl/crypto/asn1/x_algor.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2022 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
@@ -33,17 +33,14 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
     if (alg == NULL)
         return 0;
 
-    if (ptype != V_ASN1_UNDEF) {
-        if (alg->parameter == NULL)
-            alg->parameter = ASN1_TYPE_new();
-        if (alg->parameter == NULL)
-            return 0;
-    }
+    if (ptype != V_ASN1_UNDEF && alg->parameter == NULL
+            && (alg->parameter = ASN1_TYPE_new()) == NULL)
+        return 0;
 
     ASN1_OBJECT_free(alg->algorithm);
     alg->algorithm = aobj;
 
-    if (ptype == 0)
+    if (ptype == V_ASN1_EOC)
         return 1;
     if (ptype == V_ASN1_UNDEF) {
         ASN1_TYPE_free(alg->parameter);
@@ -53,6 +50,25 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
     return 1;
 }
 
+X509_ALGOR *ossl_X509_ALGOR_from_nid(int nid, int ptype, void *pval)
+{
+    ASN1_OBJECT *algo = OBJ_nid2obj(nid);
+    X509_ALGOR *alg = NULL;
+
+    if (algo == NULL)
+        return NULL;
+    if ((alg = X509_ALGOR_new()) == NULL)
+        goto err;
+    if (X509_ALGOR_set0(alg, algo, ptype, pval))
+        return alg;
+    alg->algorithm = NULL; /* precaution to prevent double free */
+
+ err:
+    X509_ALGOR_free(alg);
+    /* ASN1_OBJECT_free(algo) is not needed due to OBJ_nid2obj() */
+    return NULL;
+}
+
 void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
                      const void **ppval, const X509_ALGOR *algor)
 {
@@ -70,18 +86,12 @@ void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
 }
 
 /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
-
 void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
 {
-    int param_type;
-
-    if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
-        param_type = V_ASN1_UNDEF;
-    else
-        param_type = V_ASN1_NULL;
-
-    X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_get_type(md)), param_type, NULL);
+    int type = md->flags & EVP_MD_FLAG_DIGALGID_ABSENT ? V_ASN1_UNDEF
+                                                       : V_ASN1_NULL;
 
+    (void)X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_get_type(md)), type, NULL);
 }
 
 int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
@@ -131,13 +141,15 @@ int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src)
 /* allocate and set algorithm ID from EVP_MD, default SHA1 */
 int ossl_x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md)
 {
+    X509_ALGOR *alg;
+
     /* Default is SHA1 so no need to create it - still success */
     if (md == NULL || EVP_MD_is_a(md, "SHA1"))
         return 1;
-    *palg = X509_ALGOR_new();
-    if (*palg == NULL)
+    if ((alg = X509_ALGOR_new()) == NULL)
         return 0;
-    X509_ALGOR_set_md(*palg, md);
+    X509_ALGOR_set_md(alg, md);
+    *palg = alg;
     return 1;
 }
 
@@ -176,15 +188,12 @@ int ossl_x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md)
         goto err;
     if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL)
          goto err;
-    *palg = X509_ALGOR_new();
+    *palg = ossl_X509_ALGOR_from_nid(NID_mgf1, V_ASN1_SEQUENCE, stmp);
     if (*palg == NULL)
         goto err;
-    X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
     stmp = NULL;
  err:
     ASN1_STRING_free(stmp);
     X509_ALGOR_free(algtmp);
-    if (*palg != NULL)
-        return 1;
-    return 0;
+    return *palg != NULL;
 }

+ 1 - 3
libs/openssl/crypto/asn1/x_info.c

@@ -18,10 +18,8 @@ X509_INFO *X509_INFO_new(void)
     X509_INFO *ret;
 
     ret = OPENSSL_zalloc(sizeof(*ret));
-    if (ret == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (ret == NULL)
         return NULL;
-    }
 
     return ret;
 }

+ 3 - 7
libs/openssl/crypto/asn1/x_int64.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 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
@@ -28,10 +28,8 @@
 
 static int uint64_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-    if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint64_t))) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint64_t))) == NULL)
         return 0;
-    }
     return 1;
 }
 
@@ -123,10 +121,8 @@ static int uint64_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
 
 static int uint32_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-    if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint32_t))) == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint32_t))) == NULL)
         return 0;
-    }
     return 1;
 }
 

+ 6 - 7
libs/openssl/crypto/asn1/x_pkey.c

@@ -19,18 +19,17 @@ X509_PKEY *X509_PKEY_new(void)
 
     ret = OPENSSL_zalloc(sizeof(*ret));
     if (ret == NULL)
-        goto err;
+        return NULL;
 
     ret->enc_algor = X509_ALGOR_new();
     ret->enc_pkey = ASN1_OCTET_STRING_new();
-    if (ret->enc_algor == NULL || ret->enc_pkey == NULL)
-        goto err;
+    if (ret->enc_algor == NULL || ret->enc_pkey == NULL) {
+        X509_PKEY_free(ret);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
+        return NULL;
+    }
 
     return ret;
-err:
-    X509_PKEY_free(ret);
-    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
-    return NULL;
 }
 
 void X509_PKEY_free(X509_PKEY *x)

+ 3 - 1
libs/openssl/crypto/async/arch/async_null.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2022 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
@@ -26,5 +26,7 @@ typedef struct async_fibre_st {
 # define async_fibre_makecontext(c)             0
 # define async_fibre_free(f)
 # define async_fibre_init_dispatcher(f)
+# define async_local_init()                     1
+# define async_local_deinit()
 
 #endif

+ 3 - 0
libs/openssl/crypto/async/arch/async_posix.h

@@ -61,6 +61,9 @@ typedef struct async_fibre_st {
 #  endif
 } async_fibre;
 
+int async_local_init(void);
+void async_local_deinit(void);
+
 static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r)
 {
 #  ifdef USE_SWAPCONTEXT

+ 16 - 1
libs/openssl/crypto/async/arch/async_win.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2022 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,21 @@ int ASYNC_is_capable(void)
     return 1;
 }
 
+int ASYNC_set_mem_functions(ASYNC_stack_alloc_fn alloc_fn,
+                            ASYNC_stack_free_fn free_fn)
+{
+    return 0;
+}
+
+void ASYNC_get_mem_functions(ASYNC_stack_alloc_fn *alloc_fn,
+                             ASYNC_stack_free_fn *free_fn)
+{
+    if (alloc_fn != NULL)
+        *alloc_fn = NULL;
+    if (free_fn != NULL)
+        *free_fn = NULL;
+}
+
 void async_local_cleanup(void)
 {
     async_ctx *ctx = async_get_ctx();

+ 3 - 1
libs/openssl/crypto/async/arch/async_win.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2022 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
@@ -37,6 +37,8 @@ typedef struct async_fibre_st {
 # endif
 
 # define async_fibre_free(f)             (DeleteFiber((f)->fibre))
+# define async_local_init()              1
+# define async_local_deinit()
 
 int async_fibre_init_dispatcher(async_fibre *fibre);
 VOID CALLBACK async_start_func_win(PVOID unused);

+ 7 - 13
libs/openssl/crypto/async/async.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2022 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
@@ -40,10 +40,8 @@ static async_ctx *async_ctx_new(void)
         return NULL;
 
     nctx = OPENSSL_malloc(sizeof(*nctx));
-    if (nctx == NULL) {
-        ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE);
+    if (nctx == NULL)
         goto err;
-    }
 
     async_fibre_init_dispatcher(&nctx->dispatcher);
     nctx->currjob = NULL;
@@ -82,10 +80,8 @@ static ASYNC_JOB *async_job_new(void)
     ASYNC_JOB *job = NULL;
 
     job = OPENSSL_zalloc(sizeof(*job));
-    if (job == NULL) {
-        ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE);
+    if (job == NULL)
         return NULL;
-    }
 
     job->status = ASYNC_JOB_RUNNING;
 
@@ -256,7 +252,6 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret,
         if (args != NULL) {
             ctx->currjob->funcargs = OPENSSL_malloc(size);
             if (ctx->currjob->funcargs == NULL) {
-                ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE);
                 async_release_job(ctx->currjob);
                 ctx->currjob = NULL;
                 return ASYNC_ERR;
@@ -340,13 +335,14 @@ int async_init(void)
         return 0;
     }
 
-    return 1;
+    return async_local_init();
 }
 
 void async_deinit(void)
 {
     CRYPTO_THREAD_cleanup_local(&ctxkey);
     CRYPTO_THREAD_cleanup_local(&poolkey);
+    async_local_deinit();
 }
 
 int ASYNC_init_thread(size_t max_size, size_t init_size)
@@ -366,14 +362,12 @@ int ASYNC_init_thread(size_t max_size, size_t init_size)
         return 0;
 
     pool = OPENSSL_zalloc(sizeof(*pool));
-    if (pool == NULL) {
-        ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE);
+    if (pool == NULL)
         return 0;
-    }
 
     pool->jobs = sk_ASYNC_JOB_new_reserve(NULL, init_size);
     if (pool->jobs == NULL) {
-        ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASYNC, ERR_R_CRYPTO_LIB);
         OPENSSL_free(pool);
         return 0;
     }

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

@@ -47,10 +47,8 @@ int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key,
 {
     struct fd_lookup_st *fdlookup;
 
-    if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL) {
-        ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE);
+    if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL)
         return 0;
-    }
 
     fdlookup->key = key;
     fdlookup->fd = fd;

+ 1 - 1
libs/openssl/crypto/bf/bf_local.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2016 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

+ 6 - 7
libs/openssl/crypto/bio/bf_buff.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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
@@ -291,7 +291,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
                 return 0;
             p1 = OPENSSL_malloc((size_t)num);
             if (p1 == NULL)
-                goto malloc_error;
+                return 0;
             OPENSSL_free(ctx->ibuf);
             ctx->ibuf = p1;
         }
@@ -322,14 +322,14 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
                 return 0;
             p1 = OPENSSL_malloc((size_t)num);
             if (p1 == NULL)
-                goto malloc_error;
+                return 0;
         }
         if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
             p2 = OPENSSL_malloc((size_t)num);
             if (p2 == NULL) {
                 if (p1 != ctx->ibuf)
                     OPENSSL_free(p1);
-                goto malloc_error;
+                return 0;
             }
         }
         if (ctx->ibuf != p1) {
@@ -360,6 +360,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
             return 0;
         if (ctx->obuf_len <= 0) {
             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+            BIO_copy_next_retry(b);
             break;
         }
 
@@ -380,6 +381,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
             }
         }
         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        BIO_copy_next_retry(b);
         break;
     case BIO_CTRL_DUP:
         dbio = (BIO *)ptr;
@@ -405,9 +407,6 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
         break;
     }
     return ret;
- malloc_error:
-    ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
-    return 0;
 }
 
 static long buffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)

+ 1 - 3
libs/openssl/crypto/bio/bf_nbio.c

@@ -55,10 +55,8 @@ static int nbiof_new(BIO *bi)
 {
     NBIO_TEST *nt;
 
-    if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL) {
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+    if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL)
         return 0;
-    }
     nt->lrn = -1;
     nt->lwn = -1;
     bi->ptr = (char *)nt;

+ 46 - 25
libs/openssl/crypto/bio/bio_addr.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2023 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
@@ -53,10 +53,8 @@ BIO_ADDR *BIO_ADDR_new(void)
 {
     BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
 
-    if (ret == NULL) {
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+    if (ret == NULL)
         return NULL;
-    }
 
     ret->sa.sa_family = AF_UNSPEC;
     return ret;
@@ -67,6 +65,33 @@ void BIO_ADDR_free(BIO_ADDR *ap)
     OPENSSL_free(ap);
 }
 
+int BIO_ADDR_copy(BIO_ADDR *dst, const BIO_ADDR *src)
+{
+    if (dst == NULL || src == NULL)
+        return 0;
+
+    if (src->sa.sa_family == AF_UNSPEC) {
+        BIO_ADDR_clear(dst);
+        return 1;
+    }
+
+    return BIO_ADDR_make(dst, &src->sa);
+}
+
+BIO_ADDR *BIO_ADDR_dup(const BIO_ADDR *ap)
+{
+    BIO_ADDR *ret = NULL;
+
+    if (ap != NULL) {
+        ret = BIO_ADDR_new();
+        if (ret != NULL && !BIO_ADDR_copy(ret, ap)) {
+            BIO_ADDR_free(ret);
+            ret = NULL;
+        }
+    }
+    return ret;
+}
+
 void BIO_ADDR_clear(BIO_ADDR *ap)
 {
     memset(ap, 0, sizeof(*ap));
@@ -267,7 +292,6 @@ static int addr_strings(const BIO_ADDR *ap, int numeric,
             OPENSSL_free(*service);
             *service = NULL;
         }
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
         return 0;
     }
 
@@ -538,7 +562,7 @@ int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
         } else {
             *host = OPENSSL_strndup(h, hl);
             if (*host == NULL)
-                goto memerr;
+                return 0;
         }
     }
     if (p != NULL && service != NULL) {
@@ -548,7 +572,7 @@ int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
         } else {
             *service = OPENSSL_strndup(p, pl);
             if (*service == NULL)
-                goto memerr;
+                return 0;
         }
     }
 
@@ -559,9 +583,6 @@ int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
  spec_err:
     ERR_raise(ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE);
     return 0;
- memerr:
-    ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
-    return 0;
 }
 
 /* addrinfo_wrap is used to build our own addrinfo "chain".
@@ -578,10 +599,8 @@ static int addrinfo_wrap(int family, int socktype,
                          unsigned short port,
                          BIO_ADDRINFO **bai)
 {
-    if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL) {
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+    if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL)
         return 0;
-    }
 
     (*bai)->bai_family = family;
     (*bai)->bai_socktype = socktype;
@@ -654,7 +673,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
 {
     int ret = 0;                 /* Assume failure */
 
-    switch(family) {
+    switch (family) {
     case AF_INET:
 #if OPENSSL_USE_IPV6
     case AF_INET6:
@@ -676,7 +695,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
         if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
             return 1;
         else
-            ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
         return 0;
     }
 #endif
@@ -720,7 +739,8 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
 # endif
 # ifdef EAI_MEMORY
         case EAI_MEMORY:
-            ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+            ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
+                           gai_strerror(old_ret ? old_ret : gai_ret));
             break;
 # endif
         case 0:
@@ -777,7 +797,8 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
 #endif
 
         if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) {
-            ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+            /* Should this be raised inside do_bio_lookup_init()? */
+            ERR_raise(ERR_LIB_BIO, ERR_R_CRYPTO_LIB);
             ret = 0;
             goto err;
         }
@@ -789,7 +810,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
         he_fallback_address = INADDR_ANY;
         if (host == NULL) {
             he = &he_fallback;
-            switch(lookup_type) {
+            switch (lookup_type) {
             case BIO_LOOKUP_CLIENT:
                 he_fallback_address = INADDR_LOOPBACK;
                 break;
@@ -906,23 +927,23 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
 
             /* The easiest way to create a linked list from an
                array is to start from the back */
-            for(addrlistp = he->h_addr_list; *addrlistp != NULL;
-                addrlistp++)
+            for (addrlistp = he->h_addr_list; *addrlistp != NULL;
+                 addrlistp++)
                 ;
 
-            for(addresses = addrlistp - he->h_addr_list;
-                addrlistp--, addresses-- > 0; ) {
+            for (addresses = addrlistp - he->h_addr_list;
+                 addrlistp--, addresses-- > 0; ) {
                 if (!addrinfo_wrap(he->h_addrtype, socktype,
                                    *addrlistp, he->h_length,
                                    se->s_port, &tmp_bai))
-                    goto addrinfo_malloc_err;
+                    goto addrinfo_wrap_err;
                 tmp_bai->bai_next = *res;
                 *res = tmp_bai;
                 continue;
-             addrinfo_malloc_err:
+             addrinfo_wrap_err:
                 BIO_ADDRINFO_free(*res);
                 *res = NULL;
-                ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+                ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
                 ret = 0;
                 goto err;
             }

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

@@ -24,6 +24,8 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len,
     char *p;
     int left;
     size_t l = 0;
+    BIO_MMSG_CB_ARGS *args;
+    long ret_ = ret;
 
     if (processed != NULL)
         l = *processed;
@@ -69,6 +71,16 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len,
         BIO_snprintf(p, left, "ctrl(%d) - %s\n", argi,
                      bio->method->name);
         break;
+    case BIO_CB_RECVMMSG:
+        args = (BIO_MMSG_CB_ARGS *)argp;
+        BIO_snprintf(p, left, "recvmmsg(%zu) - %s",
+                     args->num_msg, bio->method->name);
+        break;
+    case BIO_CB_SENDMMSG:
+        args = (BIO_MMSG_CB_ARGS *)argp;
+        BIO_snprintf(p, left, "sendmmsg(%zu) - %s",
+                     args->num_msg, bio->method->name);
+        break;
     case BIO_CB_RETURN | BIO_CB_READ:
         BIO_snprintf(p, left, "read return %d processed: %zu\n", ret, l);
         break;
@@ -84,6 +96,14 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len,
     case BIO_CB_RETURN | BIO_CB_CTRL:
         BIO_snprintf(p, left, "ctrl return %d\n", ret);
         break;
+    case BIO_CB_RETURN | BIO_CB_RECVMMSG:
+        BIO_snprintf(p, left, "recvmmsg processed: %zu\n", len);
+        ret_ = (long)len;
+        break;
+    case BIO_CB_RETURN | BIO_CB_SENDMMSG:
+        BIO_snprintf(p, left, "sendmmsg processed: %zu\n", len);
+        ret_ = (long)len;
+        break;
     default:
         BIO_snprintf(p, left, "bio callback - unknown type (%d)\n", cmd);
         break;
@@ -96,7 +116,7 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len,
     else
         fputs(buf, stderr);
 #endif
-    return ret;
+    return ret_;
 }
 
 #ifndef OPENSSL_NO_DEPRECATED_3_0

+ 29 - 1
libs/openssl/crypto/bio/bio_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-2022 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
@@ -46,6 +46,10 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
     "no hostname or service specified"},
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"},
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"},
+    {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PORT_MISMATCH), "port mismatch"},
+    {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TFO_DISABLED), "tfo disabled"},
+    {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TFO_NO_KERNEL_SUPPORT),
+    "tfo no kernel support"},
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_ERROR), "transfer error"},
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_TIMEOUT), "transfer timeout"},
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET),
@@ -59,6 +63,7 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_NODELAY), "unable to nodelay"},
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_REUSEADDR),
     "unable to reuseaddr"},
+    {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_TFO), "unable to tfo"},
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNAVAILABLE_IP_FAMILY),
     "unavailable ip family"},
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNINITIALIZED), "uninitialized"},
@@ -71,6 +76,14 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WRITE_TO_READ_ONLY_BIO),
     "write to read only BIO"},
     {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WSASTARTUP), "WSAStartup"},
+    {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LOCAL_ADDR_NOT_AVAILABLE),
+     "local address not available"},
+    {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PEER_ADDR_NOT_AVAILABLE),
+     "peer address not available"},
+    {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NON_FATAL),
+     "non-fatal or transient error"},
+    {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PORT_MISMATCH),
+     "port mismatch"},
     {0, NULL}
 };
 
@@ -84,3 +97,18 @@ int ossl_err_load_BIO_strings(void)
 #endif
     return 1;
 }
+
+#ifndef OPENSSL_NO_SOCK
+
+int BIO_err_is_non_fatal(unsigned int errcode)
+{
+    if (ERR_SYSTEM_ERROR(errcode))
+        return BIO_sock_non_fatal_error(ERR_GET_REASON(errcode));
+    else if (ERR_GET_LIB(errcode) == ERR_LIB_BIO
+             && ERR_GET_REASON(errcode) == BIO_R_NON_FATAL)
+        return 1;
+    else
+        return 0;
+}
+
+#endif

+ 114 - 18
libs/openssl/crypto/bio/bio_lib.c

@@ -82,30 +82,22 @@ BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method)
 {
     BIO *bio = OPENSSL_zalloc(sizeof(*bio));
 
-    if (bio == NULL) {
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+    if (bio == NULL)
         return NULL;
-    }
 
     bio->libctx = libctx;
     bio->method = method;
     bio->shutdown = 1;
-    bio->references = 1;
 
-    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data))
+    if (!CRYPTO_NEW_REF(&bio->references, 1))
         goto err;
 
-    bio->lock = CRYPTO_THREAD_lock_new();
-    if (bio->lock == NULL) {
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
-        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data))
         goto err;
-    }
 
     if (method->create != NULL && !method->create(bio)) {
         ERR_raise(ERR_LIB_BIO, ERR_R_INIT_FAIL);
         CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
-        CRYPTO_THREAD_lock_free(bio->lock);
         goto err;
     }
     if (method->create == NULL)
@@ -114,6 +106,7 @@ BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method)
     return bio;
 
 err:
+    CRYPTO_FREE_REF(&bio->references);
     OPENSSL_free(bio);
     return NULL;
 }
@@ -130,7 +123,7 @@ int BIO_free(BIO *a)
     if (a == NULL)
         return 0;
 
-    if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0)
+    if (CRYPTO_DOWN_REF(&a->references, &ret) <= 0)
         return 0;
 
     REF_PRINT_COUNT("BIO", a);
@@ -149,7 +142,7 @@ int BIO_free(BIO *a)
 
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
 
-    CRYPTO_THREAD_lock_free(a->lock);
+    CRYPTO_FREE_REF(&a->references);
 
     OPENSSL_free(a);
 
@@ -195,7 +188,7 @@ int BIO_up_ref(BIO *a)
 {
     int i;
 
-    if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0)
+    if (CRYPTO_UP_REF(&a->references, &i) <= 0)
         return 0;
 
     REF_PRINT_COUNT("BIO", a);
@@ -398,6 +391,110 @@ int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
         || (b != NULL && dlen == 0); /* order is important for *written */
 }
 
+int BIO_sendmmsg(BIO *b, BIO_MSG *msg,
+                 size_t stride, size_t num_msg, uint64_t flags,
+                 size_t *msgs_processed)
+{
+    size_t ret;
+    BIO_MMSG_CB_ARGS args;
+
+    if (b == NULL) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (b->method == NULL || b->method->bsendmmsg == NULL) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
+        return 0;
+    }
+
+    if (HAS_CALLBACK(b)) {
+        args.msg            = msg;
+        args.stride         = stride;
+        args.num_msg        = num_msg;
+        args.flags          = flags;
+        args.msgs_processed = msgs_processed;
+
+        ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG, (void *)&args,
+                                        0, 0, 0, 1, NULL);
+        if (ret <= 0)
+            return 0;
+    }
+
+    if (!b->init) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
+        return 0;
+    }
+
+    ret = b->method->bsendmmsg(b, msg, stride, num_msg, flags, msgs_processed);
+
+    if (HAS_CALLBACK(b))
+        ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG | BIO_CB_RETURN,
+                                        (void *)&args, ret, 0, 0, ret, NULL);
+
+    return ret;
+}
+
+int BIO_recvmmsg(BIO *b, BIO_MSG *msg,
+                 size_t stride, size_t num_msg, uint64_t flags,
+                 size_t *msgs_processed)
+{
+    size_t ret;
+    BIO_MMSG_CB_ARGS args;
+
+    if (b == NULL) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (b->method == NULL || b->method->brecvmmsg == NULL) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
+        return 0;
+    }
+
+    if (HAS_CALLBACK(b)) {
+        args.msg            = msg;
+        args.stride         = stride;
+        args.num_msg        = num_msg;
+        args.flags          = flags;
+        args.msgs_processed = msgs_processed;
+
+        ret = bio_call_callback(b, BIO_CB_RECVMMSG, (void *)&args,
+                                0, 0, 0, 1, NULL);
+        if (ret <= 0)
+            return 0;
+    }
+
+    if (!b->init) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
+        return 0;
+    }
+
+    ret = b->method->brecvmmsg(b, msg, stride, num_msg, flags, msgs_processed);
+
+    if (HAS_CALLBACK(b))
+        ret = (size_t)bio_call_callback(b, BIO_CB_RECVMMSG | BIO_CB_RETURN,
+                                        (void *)&args, ret, 0, 0, ret, NULL);
+
+    return ret;
+}
+
+int BIO_get_rpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc)
+{
+    return BIO_ctrl(b, BIO_CTRL_GET_RPOLL_DESCRIPTOR, 0, desc);
+}
+
+int BIO_get_wpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc)
+{
+    return BIO_ctrl(b, BIO_CTRL_GET_WPOLL_DESCRIPTOR, 0, desc);
+}
+
 int BIO_puts(BIO *b, const char *buf)
 {
     int ret;
@@ -756,7 +853,7 @@ void BIO_free_all(BIO *bio)
 
     while (bio != NULL) {
         b = bio;
-        ref = b->references;
+        CRYPTO_GET_REF(&b->references, &ref);
         bio = bio->next_bio;
         BIO_free(b);
         /* Since ref count > 1, don't free anyone else. */
@@ -853,8 +950,7 @@ void bio_cleanup(void)
     CRYPTO_THREAD_lock_free(bio_lookup_lock);
     bio_lookup_lock = NULL;
 #endif
-    CRYPTO_THREAD_lock_free(bio_type_lock);
-    bio_type_lock = NULL;
+    CRYPTO_FREE_REF(&bio_type_count);
 }
 
 /* Internal variant of the below BIO_wait() not calling ERR_raise(...) */
@@ -886,7 +982,7 @@ static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
         if ((unsigned long)sec_diff * 1000 < nap_milliseconds)
             nap_milliseconds = (unsigned int)sec_diff * 1000;
     }
-    ossl_sleep(nap_milliseconds);
+    OSSL_sleep(nap_milliseconds);
     return 1;
 }
 

+ 9 - 14
libs/openssl/crypto/bio/bio_local.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2023 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/e_os.h"
 #include "internal/sockets.h"
+#include "internal/bio_addr.h"
 
 /* BEGIN BIO_ADDRINFO/BIO_ADDR stuff. */
 
@@ -63,17 +64,6 @@ struct bio_addrinfo_st {
     struct bio_addrinfo_st *bai_next;
 };
 # endif
-
-union bio_addr_st {
-    struct sockaddr sa;
-# if OPENSSL_USE_IPV6
-    struct sockaddr_in6 s_in6;
-# endif
-    struct sockaddr_in s_in;
-# ifndef OPENSSL_NO_UNIX_SOCK
-    struct sockaddr_un s_un;
-# endif
-};
 #endif
 
 /* END BIO_ADDRINFO/BIO_ADDR stuff. */
@@ -126,7 +116,6 @@ struct bio_st {
     uint64_t num_read;
     uint64_t num_write;
     CRYPTO_EX_DATA ex_data;
-    CRYPTO_RWLOCK *lock;
 };
 
 #ifndef OPENSSL_NO_SOCK
@@ -142,9 +131,15 @@ struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap);
 socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap);
 socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai);
 const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai);
+
+# if defined(OPENSSL_SYS_WINDOWS) && defined(WSAID_WSARECVMSG)
+#  define BIO_HAVE_WSAMSG
+extern LPFN_WSARECVMSG bio_WSARecvMsg;
+extern LPFN_WSASENDMSG bio_WSASendMsg;
+# endif
 #endif
 
-extern CRYPTO_RWLOCK *bio_type_lock;
+extern CRYPTO_REF_COUNT bio_type_count;
 
 void bio_sock_cleanup_int(void);
 

+ 28 - 8
libs/openssl/crypto/bio/bio_meth.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2023 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,25 +10,24 @@
 #include "bio_local.h"
 #include "internal/thread_once.h"
 
-CRYPTO_RWLOCK *bio_type_lock = NULL;
+CRYPTO_REF_COUNT bio_type_count;
 static CRYPTO_ONCE bio_type_init = CRYPTO_ONCE_STATIC_INIT;
 
 DEFINE_RUN_ONCE_STATIC(do_bio_type_init)
 {
-    bio_type_lock = CRYPTO_THREAD_lock_new();
-    return bio_type_lock != NULL;
+    return CRYPTO_NEW_REF(&bio_type_count, BIO_TYPE_START);
 }
 
 int BIO_get_new_index(void)
 {
-    static CRYPTO_REF_COUNT bio_count = BIO_TYPE_START;
     int newval;
 
     if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) {
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+        /* Perhaps the error should be raised in do_bio_type_init()? */
+        ERR_raise(ERR_LIB_BIO, ERR_R_CRYPTO_LIB);
         return -1;
     }
-    if (!CRYPTO_UP_REF(&bio_count, &newval, bio_type_lock))
+    if (!CRYPTO_UP_REF(&bio_type_count, &newval))
         return -1;
     return newval;
 }
@@ -40,7 +39,6 @@ BIO_METHOD *BIO_meth_new(int type, const char *name)
     if (biom == NULL
             || (biom->name = OPENSSL_strdup(name)) == NULL) {
         OPENSSL_free(biom);
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
     biom->type = type;
@@ -218,3 +216,25 @@ int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
     biom->callback_ctrl = callback_ctrl;
     return 1;
 }
+
+int BIO_meth_set_sendmmsg(BIO_METHOD *biom,
+                          int (*bsendmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *))
+{
+    biom->bsendmmsg = bsendmmsg;
+    return 1;
+}
+
+int (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) {
+    return biom->bsendmmsg;
+}
+
+int BIO_meth_set_recvmmsg(BIO_METHOD *biom,
+                          int (*brecvmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *))
+{
+    biom->brecvmmsg = brecvmmsg;
+    return 1;
+}
+
+int (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) {
+    return biom->brecvmmsg;
+}

+ 4 - 10
libs/openssl/crypto/bio/bio_print.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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
@@ -62,7 +62,7 @@ static int _dopr(char **sbuffer, char **buffer,
 #define DP_F_NUM        (1 << 3)
 /* print leading zeroes */
 #define DP_F_ZERO       (1 << 4)
-/* print HEX in UPPPERcase */
+/* print HEX in UPPERcase */
 #define DP_F_UP         (1 << 5)
 /* treat value as unsigned */
 #define DP_F_UNSIGNED   (1 << 6)
@@ -707,8 +707,6 @@ fmtfp(char **sbuffer,
         fracpart = (fracpart / 10);
     }
 
-    if (fplace == sizeof(fconvert))
-        fplace--;
     fconvert[fplace] = 0;
 
     /* convert exponent part */
@@ -847,10 +845,8 @@ doapr_outch(char **sbuffer,
 
         *maxlen += BUFFER_INC;
         if (*buffer == NULL) {
-            if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL) {
-                ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+            if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL)
                 return 0;
-            }
             if (*currlen > 0) {
                 if (!ossl_assert(*sbuffer != NULL))
                     return 0;
@@ -861,10 +857,8 @@ doapr_outch(char **sbuffer,
             char *tmpbuf;
 
             tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
-            if (tmpbuf == NULL) {
-                ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+            if (tmpbuf == NULL)
                 return 0;
-            }
             *buffer = tmpbuf;
         }
     }

+ 44 - 5
libs/openssl/crypto/bio/bio_sock.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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
@@ -130,6 +130,11 @@ struct hostent *BIO_gethostbyname(const char *name)
 }
 # endif
 
+# ifdef BIO_HAVE_WSAMSG
+LPFN_WSARECVMSG bio_WSARecvMsg;
+LPFN_WSASENDMSG bio_WSASendMsg;
+# endif
+
 int BIO_sock_init(void)
 {
 # ifdef OPENSSL_SYS_WINDOWS
@@ -150,6 +155,39 @@ int BIO_sock_init(void)
             ERR_raise(ERR_LIB_BIO, BIO_R_WSASTARTUP);
             return -1;
         }
+
+        /*
+         * On Windows, some socket functions are not exposed as a prototype.
+         * Instead, their function pointers must be loaded via this elaborate
+         * process...
+         */
+#  ifdef BIO_HAVE_WSAMSG
+        {
+            GUID id_WSARecvMsg = WSAID_WSARECVMSG;
+            GUID id_WSASendMsg = WSAID_WSASENDMSG;
+            DWORD len_out = 0;
+            SOCKET s;
+
+            s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+            if (s != INVALID_SOCKET) {
+                if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
+                             &id_WSARecvMsg, sizeof(id_WSARecvMsg),
+                             &bio_WSARecvMsg, sizeof(bio_WSARecvMsg),
+                             &len_out, NULL, NULL) != 0
+                    || len_out != sizeof(bio_WSARecvMsg))
+                    bio_WSARecvMsg = NULL;
+
+                if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
+                             &id_WSASendMsg, sizeof(id_WSASendMsg),
+                             &bio_WSASendMsg, sizeof(bio_WSASendMsg),
+                             &len_out, NULL, NULL) != 0
+                    || len_out != sizeof(bio_WSASendMsg))
+                    bio_WSASendMsg = NULL;
+
+                closesocket(s);
+            }
+        }
+#  endif
     }
 # endif                         /* OPENSSL_SYS_WINDOWS */
 # ifdef WATT32
@@ -267,13 +305,14 @@ int BIO_accept(int sock, char **ip_port)
     if (ip_port != NULL) {
         char *host = BIO_ADDR_hostname_string(&res, 1);
         char *port = BIO_ADDR_service_string(&res, 1);
-        if (host != NULL && port != NULL)
+        if (host != NULL && port != NULL) {
             *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2);
-        else
+        } else {
             *ip_port = NULL;
+            ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
+        }
 
         if (*ip_port == NULL) {
-            ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
             BIO_closesocket(ret);
             ret = (int)INVALID_SOCKET;
         } else {
@@ -315,7 +354,7 @@ int BIO_socket_nbio(int s, int mode)
     int l;
 
     l = mode;
-# ifdef FIONBIO
+# if defined(FIONBIO) && !defined(OPENSSL_SYS_TANDEM)
     l = mode;
 
     ret = BIO_socket_ioctl(s, FIONBIO, &l);

+ 113 - 0
libs/openssl/crypto/bio/bio_sock2.c

@@ -13,6 +13,7 @@
 
 #include "bio_local.h"
 #include "internal/ktls.h"
+#include "internal/bio_tfo.h"
 
 #include <openssl/err.h>
 
@@ -68,6 +69,7 @@ int BIO_socket(int domain, int socktype, int protocol, int options)
  * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
  * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
  * - BIO_SOCK_NODELAY: don't delay small messages.
+ * - BIO_SOCK_TFO: use TCP Fast Open
  *
  * options holds BIO socket options that can be used
  * You should call this for every address returned by BIO_lookup
@@ -107,6 +109,68 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options)
             return 0;
         }
     }
+    if (options & BIO_SOCK_TFO) {
+# if defined(OSSL_TFO_CLIENT_FLAG)
+#  if defined(OSSL_TFO_SYSCTL_CLIENT)
+        int enabled = 0;
+        size_t enabledlen = sizeof(enabled);
+
+        /* Later FreeBSD */
+        if (sysctlbyname(OSSL_TFO_SYSCTL_CLIENT, &enabled, &enabledlen, NULL, 0) < 0) {
+            ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT);
+            return 0;
+        }
+        /* Need to check for client flag */
+        if (!(enabled & OSSL_TFO_CLIENT_FLAG)) {
+            ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED);
+            return 0;
+        }
+#  elif defined(OSSL_TFO_SYSCTL)
+        int enabled = 0;
+        size_t enabledlen = sizeof(enabled);
+
+        /* macOS */
+        if (sysctlbyname(OSSL_TFO_SYSCTL, &enabled, &enabledlen, NULL, 0) < 0) {
+            ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT);
+            return 0;
+        }
+        /* Need to check for client flag */
+        if (!(enabled & OSSL_TFO_CLIENT_FLAG)) {
+            ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED);
+            return 0;
+        }
+#  endif
+# endif
+# if defined(OSSL_TFO_CONNECTX)
+        sa_endpoints_t sae;
+
+        memset(&sae, 0, sizeof(sae));
+        sae.sae_dstaddr = BIO_ADDR_sockaddr(addr);
+        sae.sae_dstaddrlen = BIO_ADDR_sockaddr_size(addr);
+        if (connectx(sock, &sae, SAE_ASSOCID_ANY,
+                     CONNECT_DATA_IDEMPOTENT | CONNECT_RESUME_ON_READ_WRITE,
+                     NULL, 0, NULL, NULL) == -1) {
+            if (!BIO_sock_should_retry(-1)) {
+                ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+                               "calling connectx()");
+                ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
+            }
+            return 0;
+        }
+# endif
+# if defined(OSSL_TFO_CLIENT_SOCKOPT)
+        if (setsockopt(sock, IPPROTO_TCP, OSSL_TFO_CLIENT_SOCKOPT,
+                       (const void *)&on, sizeof(on)) != 0) {
+            ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+                           "calling setsockopt()");
+            ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_TFO);
+            return 0;
+        }
+# endif
+# if defined(OSSL_TFO_DO_NOT_CONNECT)
+        return 1;
+# endif
+    }
 
     if (connect(sock, BIO_ADDR_sockaddr(addr),
                 BIO_ADDR_sockaddr_size(addr)) == -1) {
@@ -199,6 +263,7 @@ int BIO_bind(int sock, const BIO_ADDR *addr, int options)
  *   for a recently closed port.
  * - BIO_SOCK_V6_ONLY: When creating an IPv6 socket, make it listen only
  *   for IPv6 addresses and not IPv4 addresses mapped to IPv6.
+ * - BIO_SOCK_TFO: accept TCP fast open (set TCP_FASTOPEN)
  *
  * It's recommended that you set up both an IPv6 and IPv4 listen socket, and
  * then check both for new clients that connect to it.  You want to set up
@@ -290,6 +355,54 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
         return 0;
     }
 
+# if defined(OSSL_TFO_SERVER_SOCKOPT)
+    /*
+     * Must do it explicitly after listen() for macOS, still
+     * works fine on other OS's
+     */
+    if ((options & BIO_SOCK_TFO) && socktype != SOCK_DGRAM) {
+        int q = OSSL_TFO_SERVER_SOCKOPT_VALUE;
+#  if defined(OSSL_TFO_CLIENT_FLAG)
+#   if defined(OSSL_TFO_SYSCTL_SERVER)
+        int enabled = 0;
+        size_t enabledlen = sizeof(enabled);
+
+        /* Later FreeBSD */
+        if (sysctlbyname(OSSL_TFO_SYSCTL_SERVER, &enabled, &enabledlen, NULL, 0) < 0) {
+            ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT);
+            return 0;
+        }
+        /* Need to check for server flag */
+        if (!(enabled & OSSL_TFO_SERVER_FLAG)) {
+            ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED);
+            return 0;
+        }
+#   elif defined(OSSL_TFO_SYSCTL)
+        int enabled = 0;
+        size_t enabledlen = sizeof(enabled);
+
+        /* Early FreeBSD, macOS */
+        if (sysctlbyname(OSSL_TFO_SYSCTL, &enabled, &enabledlen, NULL, 0) < 0) {
+            ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT);
+            return 0;
+        }
+        /* Need to check for server flag */
+        if (!(enabled & OSSL_TFO_SERVER_FLAG)) {
+            ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED);
+            return 0;
+        }
+#   endif
+#  endif
+        if (setsockopt(sock, IPPROTO_TCP, OSSL_TFO_SERVER_SOCKOPT,
+                       (void *)&q, sizeof(q)) < 0) {
+            ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+                           "calling setsockopt()");
+            ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_TFO);
+            return 0;
+        }
+    }
+# endif
+
     return 1;
 }
 

+ 5 - 3
libs/openssl/crypto/bio/bss_acpt.c

@@ -92,10 +92,8 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void)
 {
     BIO_ACCEPT *ret;
 
-    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
         return NULL;
-    }
     ret->accept_family = BIO_FAMILY_IPANY;
     ret->accept_sock = (int)INVALID_SOCKET;
     return ret;
@@ -452,10 +450,14 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
                 data->bio_chain = (BIO *)ptr;
             } else if (num == 4) {
                 data->accept_family = *(int *)ptr;
+            } else if (num == 5) {
+                data->bind_mode |= BIO_SOCK_TFO;
             }
         } else {
             if (num == 2) {
                 data->bind_mode &= ~BIO_SOCK_NONBLOCK;
+            } else if (num == 5) {
+                data->bind_mode &= ~BIO_SOCK_TFO;
             }
         }
         break;

+ 3 - 7
libs/openssl/crypto/bio/bss_bio.c

@@ -273,7 +273,7 @@ static int bio_write(BIO *bio, const char *buf, int num_)
 
     BIO_clear_retry_flags(bio);
 
-    if (!bio->init || buf == NULL || num == 0)
+    if (!bio->init || buf == NULL || num_ <= 0)
         return 0;
 
     b = bio->ptr;
@@ -620,20 +620,16 @@ static int bio_make_pair(BIO *bio1, BIO *bio2)
 
     if (b1->buf == NULL) {
         b1->buf = OPENSSL_malloc(b1->size);
-        if (b1->buf == NULL) {
-            ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+        if (b1->buf == NULL)
             return 0;
-        }
         b1->len = 0;
         b1->offset = 0;
     }
 
     if (b2->buf == NULL) {
         b2->buf = OPENSSL_malloc(b2->size);
-        if (b2->buf == NULL) {
-            ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+        if (b2->buf == NULL)
             return 0;
-        }
         b2->len = 0;
         b2->offset = 0;
     }

+ 273 - 10
libs/openssl/crypto/bio/bss_conn.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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,6 +11,7 @@
 #include <errno.h>
 
 #include "bio_local.h"
+#include "internal/bio_tfo.h"
 #include "internal/ktls.h"
 
 #ifndef OPENSSL_NO_SOCK
@@ -18,12 +19,14 @@
 typedef struct bio_connect_st {
     int state;
     int connect_family;
+    int connect_sock_type;
     char *param_hostname;
     char *param_service;
     int connect_mode;
 # ifndef OPENSSL_NO_KTLS
     unsigned char record_type;
 # endif
+    int tfo_first;
 
     BIO_ADDRINFO *addr_first;
     const BIO_ADDRINFO *addr_iter;
@@ -37,20 +40,30 @@ typedef struct bio_connect_st {
      * ssl info_callback
      */
     BIO_info_cb *info_callback;
+    /*
+     * Used when connect_sock_type is SOCK_DGRAM. Owned by us; we forward
+     * read/write(mmsg) calls to this if present.
+     */
+    BIO *dgram_bio;
 } BIO_CONNECT;
 
 static int conn_write(BIO *h, const char *buf, int num);
 static int conn_read(BIO *h, char *buf, int size);
 static int conn_puts(BIO *h, const char *str);
+static int conn_gets(BIO *h, char *buf, int size);
 static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
 static int conn_new(BIO *h);
 static int conn_free(BIO *data);
 static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *);
+static int conn_sendmmsg(BIO *h, BIO_MSG *m, size_t s, size_t n,
+                         uint64_t f, size_t *mp);
+static int conn_recvmmsg(BIO *h, BIO_MSG *m, size_t s, size_t n,
+                         uint64_t f, size_t *mp);
 
 static int conn_state(BIO *b, BIO_CONNECT *c);
 static void conn_close_socket(BIO *data);
-BIO_CONNECT *BIO_CONNECT_new(void);
-void BIO_CONNECT_free(BIO_CONNECT *a);
+static BIO_CONNECT *BIO_CONNECT_new(void);
+static void BIO_CONNECT_free(BIO_CONNECT *a);
 
 #define BIO_CONN_S_BEFORE                1
 #define BIO_CONN_S_GET_ADDR              2
@@ -68,13 +81,33 @@ static const BIO_METHOD methods_connectp = {
     bread_conv,
     conn_read,
     conn_puts,
-    NULL,                       /* conn_gets, */
+    conn_gets,
     conn_ctrl,
     conn_new,
     conn_free,
     conn_callback_ctrl,
+    conn_sendmmsg,
+    conn_recvmmsg,
 };
 
+static int conn_create_dgram_bio(BIO *b, BIO_CONNECT *c)
+{
+    if (c->connect_sock_type != SOCK_DGRAM)
+        return 1;
+
+#ifndef OPENSSL_NO_DGRAM
+    c->dgram_bio = BIO_new_dgram(b->num, 0);
+    if (c->dgram_bio == NULL)
+        goto err;
+
+    return 1;
+
+err:
+#endif
+    c->state = BIO_CONN_S_CONNECT_ERROR;
+    return 0;
+}
+
 static int conn_state(BIO *b, BIO_CONNECT *c)
 {
     int ret = -1, i;
@@ -125,7 +158,8 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
                 }
                 if (BIO_lookup(c->param_hostname, c->param_service,
                                BIO_LOOKUP_CLIENT,
-                               family, SOCK_STREAM, &c->addr_first) == 0)
+                               family, c->connect_sock_type,
+                               &c->addr_first) == 0)
                     goto exit_loop;
             }
             if (c->addr_first == NULL) {
@@ -183,6 +217,8 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
                 goto exit_loop;
             } else {
                 ERR_clear_last_mark();
+                if (!conn_create_dgram_bio(b, c))
+                    break;
                 c->state = BIO_CONN_S_OK;
             }
             break;
@@ -209,6 +245,8 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
                 ret = 0;
                 goto exit_loop;
             } else {
+                if (!conn_create_dgram_bio(b, c))
+                    break;
                 c->state = BIO_CONN_S_OK;
 # ifndef OPENSSL_NO_KTLS
                 /*
@@ -249,20 +287,19 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
     return ret;
 }
 
-BIO_CONNECT *BIO_CONNECT_new(void)
+static BIO_CONNECT *BIO_CONNECT_new(void)
 {
     BIO_CONNECT *ret;
 
-    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
         return NULL;
-    }
     ret->state = BIO_CONN_S_BEFORE;
     ret->connect_family = BIO_FAMILY_IPANY;
+    ret->connect_sock_type = SOCK_STREAM;
     return ret;
 }
 
-void BIO_CONNECT_free(BIO_CONNECT *a)
+static void BIO_CONNECT_free(BIO_CONNECT *a)
 {
     if (a == NULL)
         return;
@@ -310,6 +347,8 @@ static int conn_free(BIO *a)
         return 0;
     data = (BIO_CONNECT *)a->ptr;
 
+    BIO_free(data->dgram_bio);
+
     if (a->shutdown) {
         conn_close_socket(a);
         BIO_CONNECT_free(data);
@@ -332,6 +371,13 @@ static int conn_read(BIO *b, char *out, int outl)
             return ret;
     }
 
+    if (data->dgram_bio != NULL) {
+        BIO_clear_retry_flags(b);
+        ret = BIO_read(data->dgram_bio, out, outl);
+        BIO_set_flags(b, BIO_get_retry_flags(data->dgram_bio));
+        return ret;
+    }
+
     if (out != NULL) {
         clear_socket_error();
 # ifndef OPENSSL_NO_KTLS
@@ -363,6 +409,13 @@ static int conn_write(BIO *b, const char *in, int inl)
             return ret;
     }
 
+    if (data->dgram_bio != NULL) {
+        BIO_clear_retry_flags(b);
+        ret = BIO_write(data->dgram_bio, in, inl);
+        BIO_set_flags(b, BIO_get_retry_flags(data->dgram_bio));
+        return ret;
+    }
+
     clear_socket_error();
 # ifndef OPENSSL_NO_KTLS
     if (BIO_should_ktls_ctrl_msg_flag(b)) {
@@ -372,6 +425,15 @@ static int conn_write(BIO *b, const char *in, int inl)
             BIO_clear_ktls_ctrl_msg_flag(b);
         }
     } else
+# endif
+# if defined(OSSL_TFO_SENDTO)
+    if (data->tfo_first) {
+        int peerlen = BIO_ADDRINFO_sockaddr_size(data->addr_iter);
+
+        ret = sendto(b->num, in, inl, OSSL_TFO_SENDTO,
+                     BIO_ADDRINFO_sockaddr(data->addr_iter), peerlen);
+        data->tfo_first = 0;
+    } else
 # endif
         ret = writesocket(b->num, in, inl);
     BIO_clear_retry_flags(b);
@@ -389,6 +451,7 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
     const char **pptr = NULL;
     long ret = 1;
     BIO_CONNECT *data;
+    const BIO_ADDR *dg_addr;
 # ifndef OPENSSL_NO_KTLS
     ktls_crypto_info_t *crypto_info;
 # endif
@@ -437,6 +500,8 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
                     ret = -1;
                     break;
                 }
+            } else if (num == 4) {
+                ret = data->connect_mode;
             } else {
                 ret = 0;
             }
@@ -491,14 +556,90 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
             }
         }
         break;
+    case BIO_C_SET_SOCK_TYPE:
+        if ((num != SOCK_STREAM && num != SOCK_DGRAM)
+            || data->state >= BIO_CONN_S_GET_ADDR) {
+            ret = 0;
+            break;
+        }
+
+        data->connect_sock_type = (int)num;
+        ret = 1;
+        break;
+    case BIO_C_GET_SOCK_TYPE:
+        ret = data->connect_sock_type;
+        break;
+    case BIO_C_GET_DGRAM_BIO:
+        if (data->dgram_bio != NULL) {
+            *(BIO **)ptr = data->dgram_bio;
+            ret = 1;
+        } else {
+            ret = 0;
+        }
+        break;
+    case BIO_CTRL_DGRAM_GET_PEER:
+    case BIO_CTRL_DGRAM_DETECT_PEER_ADDR:
+        if (data->state != BIO_CONN_S_OK)
+            conn_state(b, data); /* best effort */
+
+        if (data->state >= BIO_CONN_S_CREATE_SOCKET
+            && data->addr_iter != NULL
+            && (dg_addr = BIO_ADDRINFO_address(data->addr_iter)) != NULL) {
+
+            ret = BIO_ADDR_sockaddr_size(dg_addr);
+            if (num == 0 || num > ret)
+                num = ret;
+
+            memcpy(ptr, dg_addr, num);
+            ret = num;
+        } else {
+            ret = 0;
+        }
+
+        break;
+    case BIO_CTRL_GET_RPOLL_DESCRIPTOR:
+    case BIO_CTRL_GET_WPOLL_DESCRIPTOR:
+        {
+            BIO_POLL_DESCRIPTOR *pd = ptr;
+
+            if (data->state != BIO_CONN_S_OK)
+                conn_state(b, data); /* best effort */
+
+            if (data->state >= BIO_CONN_S_CREATE_SOCKET) {
+                pd->type        = BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD;
+                pd->value.fd    = b->num;
+            } else {
+                ret = 0;
+            }
+        }
+        break;
     case BIO_C_SET_NBIO:
         if (num != 0)
             data->connect_mode |= BIO_SOCK_NONBLOCK;
         else
             data->connect_mode &= ~BIO_SOCK_NONBLOCK;
+
+        if (data->dgram_bio != NULL)
+            ret = BIO_set_nbio(data->dgram_bio, num);
+
         break;
+#if defined(TCP_FASTOPEN) && !defined(OPENSSL_NO_TFO)
+    case BIO_C_SET_TFO:
+        if (num != 0) {
+            data->connect_mode |= BIO_SOCK_TFO;
+            data->tfo_first = 1;
+        } else {
+            data->connect_mode &= ~BIO_SOCK_TFO;
+            data->tfo_first = 0;
+        }
+        break;
+#endif
     case BIO_C_SET_CONNECT_MODE:
         data->connect_mode = (int)num;
+        if (num & BIO_SOCK_TFO)
+            data->tfo_first = 1;
+        else
+            data->tfo_first = 0;
         break;
     case BIO_C_GET_FD:
         if (b->init) {
@@ -571,6 +712,11 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
         BIO_clear_ktls_ctrl_msg_flag(b);
         ret = 0;
         break;
+    case BIO_CTRL_SET_KTLS_TX_ZEROCOPY_SENDFILE:
+        ret = ktls_enable_tx_zerocopy_sendfile(b->num);
+        if (ret)
+            BIO_set_ktls_zerocopy_sendfile_flag(b);
+        break;
 # endif
     default:
         ret = 0;
@@ -608,6 +754,123 @@ static int conn_puts(BIO *bp, const char *str)
     return ret;
 }
 
+int conn_gets(BIO *bio, char *buf, int size)
+{
+    BIO_CONNECT *data;
+    char *ptr = buf;
+    int ret = 0;
+
+    if (buf == NULL) {
+        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+        return -1;
+    }
+    if (size <= 0) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
+        return -1;
+    }
+    *buf = '\0';
+
+    if (bio == NULL || bio->ptr == NULL) {
+        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+        return -1;
+    }
+    data = (BIO_CONNECT *)bio->ptr;
+    if (data->state != BIO_CONN_S_OK) {
+        ret = conn_state(bio, data);
+        if (ret <= 0)
+            return ret;
+    }
+
+    if (data->dgram_bio != NULL) {
+        ERR_raise(ERR_LIB_BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return -1;
+    }
+
+    clear_socket_error();
+    while (size-- > 1) {
+# ifndef OPENSSL_NO_KTLS
+        if (BIO_get_ktls_recv(bio))
+            ret = ktls_read_record(bio->num, ptr, 1);
+        else
+# endif
+            ret = readsocket(bio->num, ptr, 1);
+        BIO_clear_retry_flags(bio);
+        if (ret <= 0) {
+            if (BIO_sock_should_retry(ret))
+                BIO_set_retry_read(bio);
+            else if (ret == 0)
+                bio->flags |= BIO_FLAGS_IN_EOF;
+            break;
+        }
+        if (*ptr++ == '\n')
+            break;
+    }
+    *ptr = '\0';
+    return ret > 0 || (bio->flags & BIO_FLAGS_IN_EOF) != 0 ? ptr - buf : ret;
+}
+
+static int conn_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, size_t num_msgs,
+                         uint64_t flags, size_t *msgs_processed)
+{
+    int ret;
+    BIO_CONNECT *data;
+
+    if (bio == NULL) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    data = (BIO_CONNECT *)bio->ptr;
+    if (data->state != BIO_CONN_S_OK) {
+        ret = conn_state(bio, data);
+        if (ret <= 0) {
+            *msgs_processed = 0;
+            return 0;
+        }
+    }
+
+    if (data->dgram_bio == NULL) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    return BIO_sendmmsg(data->dgram_bio, msg, stride, num_msgs,
+                        flags, msgs_processed);
+}
+
+static int conn_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, size_t num_msgs,
+                         uint64_t flags, size_t *msgs_processed)
+{
+    int ret;
+    BIO_CONNECT *data;
+
+    if (bio == NULL) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    data = (BIO_CONNECT *)bio->ptr;
+    if (data->state != BIO_CONN_S_OK) {
+        ret = conn_state(bio, data);
+        if (ret <= 0) {
+            *msgs_processed = 0;
+            return 0;
+        }
+    }
+
+    if (data->dgram_bio == NULL) {
+        *msgs_processed = 0;
+        ERR_raise(ERR_LIB_BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    return BIO_recvmmsg(data->dgram_bio, msg, stride, num_msgs,
+                        flags, msgs_processed);
+}
+
 BIO *BIO_new_connect(const char *str)
 {
     BIO *ret;

+ 1328 - 0
libs/openssl/crypto/bio/bss_dgram_pair.c

@@ -0,0 +1,1328 @@
+/*
+ * Copyright 2022-2023 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 <errno.h>
+#include "bio_local.h"
+#include "internal/cryptlib.h"
+#include "internal/safe_math.h"
+
+#if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK)
+
+OSSL_SAFE_MATH_UNSIGNED(size_t, size_t)
+
+/* ===========================================================================
+ * Byte-wise ring buffer which supports pushing and popping blocks of multiple
+ * bytes at a time.
+ */
+struct ring_buf {
+    unsigned char *start; /* start of buffer */
+    size_t len; /* size of buffer allocation in bytes */
+    size_t count; /* number of bytes currently pushed */
+    /*
+     * These index into start. Where idx[0] == idx[1], the buffer is full
+     * (if count is nonzero) and empty otherwise.
+     */
+    size_t idx[2]; /* 0: head, 1: tail */
+};
+
+static int ring_buf_init(struct ring_buf *r, size_t nbytes)
+{
+    r->start = OPENSSL_malloc(nbytes);
+    if (r->start == NULL)
+        return 0;
+
+    r->len = nbytes;
+    r->idx[0] = r->idx[1] = r->count = 0;
+    return 1;
+}
+
+static void ring_buf_destroy(struct ring_buf *r)
+{
+    OPENSSL_free(r->start);
+    r->start    = NULL;
+    r->len      = 0;
+    r->count    = 0;
+}
+
+/*
+ * Get a pointer to the next place to write data to be pushed to the ring buffer
+ * (idx=0), or the next data to be popped from the ring buffer (idx=1). The
+ * pointer is written to *buf and the maximum number of bytes which can be
+ * read/written are written to *len. After writing data to the buffer, call
+ * ring_buf_push/pop() with the number of bytes actually read/written, which
+ * must not exceed the returned length.
+ */
+static void ring_buf_head_tail(struct ring_buf *r, int idx, uint8_t **buf, size_t *len)
+{
+    size_t max_len = r->len - r->idx[idx];
+
+    if (idx == 0 && max_len > r->len - r->count)
+        max_len = r->len - r->count;
+    if (idx == 1 && max_len > r->count)
+        max_len = r->count;
+
+    *buf = (uint8_t *)r->start + r->idx[idx];
+    *len = max_len;
+}
+
+#define ring_buf_head(r, buf, len) ring_buf_head_tail((r), 0, (buf), (len))
+#define ring_buf_tail(r, buf, len) ring_buf_head_tail((r), 1, (buf), (len))
+
+/*
+ * Commit bytes to the ring buffer previously filled after a call to
+ * ring_buf_head().
+ */
+static void ring_buf_push_pop(struct ring_buf *r, int idx, size_t num_bytes)
+{
+    size_t new_idx;
+
+    /* A single push/pop op cannot wrap around, though it can reach the end.
+     * If the caller adheres to the convention of using the length returned
+     * by ring_buf_head/tail(), this cannot happen.
+     */
+    if (!ossl_assert(num_bytes <= r->len - r->idx[idx]))
+        return;
+
+    /*
+     * Must not overfill the buffer, or pop more than is in the buffer either.
+     */
+    if (!ossl_assert(idx != 0 ? num_bytes <= r->count
+                              : num_bytes + r->count <= r->len))
+        return;
+
+    /* Update the index. */
+    new_idx = r->idx[idx] + num_bytes;
+    if (new_idx == r->len)
+        new_idx = 0;
+
+    r->idx[idx] = new_idx;
+    if (idx != 0)
+        r->count -= num_bytes;
+    else
+        r->count += num_bytes;
+}
+
+#define ring_buf_push(r, num_bytes) ring_buf_push_pop((r), 0, (num_bytes))
+#define ring_buf_pop(r, num_bytes) ring_buf_push_pop((r), 1, (num_bytes))
+
+static void ring_buf_clear(struct ring_buf *r)
+{
+    r->idx[0] = r->idx[1] = r->count = 0;
+}
+
+static int ring_buf_resize(struct ring_buf *r, size_t nbytes)
+{
+    unsigned char *new_start;
+
+    if (r->start == NULL)
+        return ring_buf_init(r, nbytes);
+
+    if (nbytes == r->len)
+        return 1;
+
+    if (r->count > 0 && nbytes < r->len)
+        /* fail shrinking the ring buffer when there is any data in it */
+        return 0;
+
+    new_start = OPENSSL_realloc(r->start, nbytes);
+    if (new_start == NULL)
+        return 0;
+
+    /* Moving tail if it is after (or equal to) head */
+    if (r->count > 0) {
+        if (r->idx[0] <= r->idx[1]) {
+            size_t offset = nbytes - r->len;
+
+            memmove(new_start + r->idx[1] + offset, new_start + r->idx[1],
+                    r->len - r->idx[1]);
+            r->idx[1] += offset;
+        }
+    } else {
+        /* just reset the head/tail because it might be pointing outside */
+        r->idx[0] = r->idx[1] = 0;
+    }
+
+    r->start = new_start;
+    r->len = nbytes;
+
+    return 1;
+}
+
+/* ===========================================================================
+ * BIO_s_dgram_pair is documented in BIO_s_dgram_pair(3).
+ *
+ * INTERNAL DATA STRUCTURE
+ *
+ * This is managed internally by using a bytewise ring buffer which supports
+ * pushing and popping spans of multiple bytes at once. The ring buffer stores
+ * internal packets which look like this:
+ *
+ *   struct dgram_hdr hdr;
+ *   uint8_t data[];
+ *
+ * The header contains the length of the data and metadata such as
+ * source/destination addresses.
+ *
+ * The datagram pair BIO is designed to support both traditional
+ * BIO_read/BIO_write (likely to be used by applications) as well as
+ * BIO_recvmmsg/BIO_sendmmsg.
+ */
+struct bio_dgram_pair_st;
+static int dgram_pair_write(BIO *bio, const char *buf, int sz_);
+static int dgram_pair_read(BIO *bio, char *buf, int sz_);
+static int dgram_mem_read(BIO *bio, char *buf, int sz_);
+static long dgram_pair_ctrl(BIO *bio, int cmd, long num, void *ptr);
+static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr);
+static int dgram_pair_init(BIO *bio);
+static int dgram_mem_init(BIO *bio);
+static int dgram_pair_free(BIO *bio);
+static int dgram_pair_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride,
+                               size_t num_msg, uint64_t flags,
+                               size_t *num_processed);
+static int dgram_pair_recvmmsg(BIO *b, BIO_MSG *msg, size_t stride,
+                               size_t num_msg, uint64_t flags,
+                               size_t *num_processed);
+
+static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1);
+static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf,
+                                    size_t sz);
+
+#define BIO_MSG_N(array, n) (*(BIO_MSG *)((char *)(array) + (n)*stride))
+
+static const BIO_METHOD dgram_pair_method = {
+    BIO_TYPE_DGRAM_PAIR,
+    "BIO dgram pair",
+    bwrite_conv,
+    dgram_pair_write,
+    bread_conv,
+    dgram_pair_read,
+    NULL, /* dgram_pair_puts */
+    NULL, /* dgram_pair_gets */
+    dgram_pair_ctrl,
+    dgram_pair_init,
+    dgram_pair_free,
+    NULL, /* dgram_pair_callback_ctrl */
+    dgram_pair_sendmmsg,
+    dgram_pair_recvmmsg,
+};
+
+static const BIO_METHOD dgram_mem_method = {
+    BIO_TYPE_DGRAM_MEM,
+    "BIO dgram mem",
+    bwrite_conv,
+    dgram_pair_write,
+    bread_conv,
+    dgram_mem_read,
+    NULL, /* dgram_pair_puts */
+    NULL, /* dgram_pair_gets */
+    dgram_mem_ctrl,
+    dgram_mem_init,
+    dgram_pair_free,
+    NULL, /* dgram_pair_callback_ctrl */
+    dgram_pair_sendmmsg,
+    dgram_pair_recvmmsg,
+};
+
+const BIO_METHOD *BIO_s_dgram_pair(void)
+{
+    return &dgram_pair_method;
+}
+
+const BIO_METHOD *BIO_s_dgram_mem(void)
+{
+    return &dgram_mem_method;
+}
+
+struct dgram_hdr {
+    size_t len; /* payload length in bytes, not including this struct */
+    BIO_ADDR src_addr, dst_addr; /* family == 0: not present */
+};
+
+struct bio_dgram_pair_st {
+    /* The other half of the BIO pair. NULL for dgram_mem. */
+    BIO *peer;
+    /* Writes are directed to our own ringbuf and reads to our peer. */
+    struct ring_buf rbuf;
+    /* Requested size of rbuf buffer in bytes once we initialize. */
+    size_t req_buf_len;
+    /* Largest possible datagram size */
+    size_t mtu;
+    /* Capability flags. */
+    uint32_t cap;
+    /*
+     * 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
+     * reads.
+     */
+    CRYPTO_RWLOCK *lock;
+    unsigned int no_trunc          : 1; /* Reads fail if they would truncate */
+    unsigned int local_addr_enable : 1; /* Can use BIO_MSG->local? */
+    unsigned int role              : 1; /* Determines lock order */
+    unsigned int grows_on_write    : 1; /* Set for BIO_s_dgram_mem only */
+};
+
+#define MIN_BUF_LEN (1024)
+
+#define is_dgram_pair(b) (b->peer != NULL)
+
+static int dgram_pair_init(BIO *bio)
+{
+    struct bio_dgram_pair_st *b = OPENSSL_zalloc(sizeof(*b));
+
+    if (b == NULL)
+        return 0;
+
+    b->mtu         = 1472;    /* conservative default MTU */
+    /* default buffer size */
+    b->req_buf_len = 9 * (sizeof(struct dgram_hdr) + b->mtu);
+
+    b->lock = CRYPTO_THREAD_lock_new();
+    if (b->lock == NULL) {
+        OPENSSL_free(b);
+        return 0;
+    }
+
+    bio->ptr = b;
+    return 1;
+}
+
+static int dgram_mem_init(BIO *bio)
+{
+    struct bio_dgram_pair_st *b;
+
+    if (!dgram_pair_init(bio))
+        return 0;
+
+    b = bio->ptr;
+
+    if (ring_buf_init(&b->rbuf, b->req_buf_len) == 0) {
+        ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
+        return 0;
+    }
+
+    b->grows_on_write = 1;
+
+    bio->init = 1;
+    return 1;
+}
+
+static int dgram_pair_free(BIO *bio)
+{
+    struct bio_dgram_pair_st *b;
+
+    if (bio == NULL)
+        return 0;
+
+    b = bio->ptr;
+    if (!ossl_assert(b != NULL))
+        return 0;
+
+    /* We are being freed. Disconnect any peer and destroy buffers. */
+    dgram_pair_ctrl_destroy_bio_pair(bio);
+
+    CRYPTO_THREAD_lock_free(b->lock);
+    OPENSSL_free(b);
+    return 1;
+}
+
+/* BIO_make_bio_pair (BIO_C_MAKE_BIO_PAIR) */
+static int dgram_pair_ctrl_make_bio_pair(BIO *bio1, BIO *bio2)
+{
+    struct bio_dgram_pair_st *b1, *b2;
+
+    /* peer must be non-NULL. */
+    if (bio1 == NULL || bio2 == NULL) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
+        return 0;
+    }
+
+    /* Ensure the BIO we have been passed is actually a dgram pair BIO. */
+    if (bio1->method != &dgram_pair_method || bio2->method != &dgram_pair_method) {
+        ERR_raise_data(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT,
+                       "both BIOs must be BIO_dgram_pair");
+        return 0;
+    }
+
+    b1 = bio1->ptr;
+    b2 = bio2->ptr;
+
+    if (!ossl_assert(b1 != NULL && b2 != NULL)) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
+        return 0;
+    }
+
+    /*
+     * This ctrl cannot be used to associate a BIO pair half which is already
+     * associated.
+     */
+    if (b1->peer != NULL || b2->peer != NULL) {
+        ERR_raise_data(ERR_LIB_BIO, BIO_R_IN_USE,
+                       "cannot associate a BIO_dgram_pair which is already in use");
+        return 0;
+    }
+
+    if (!ossl_assert(b1->req_buf_len >= MIN_BUF_LEN
+                        && b2->req_buf_len >= MIN_BUF_LEN)) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
+        return 0;
+    }
+
+    if (b1->rbuf.len != b1->req_buf_len)
+        if (ring_buf_init(&b1->rbuf, b1->req_buf_len) == 0) {
+            ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
+            return 0;
+        }
+
+    if (b2->rbuf.len != b2->req_buf_len)
+        if (ring_buf_init(&b2->rbuf, b2->req_buf_len) == 0) {
+            ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
+            ring_buf_destroy(&b1->rbuf);
+            return 0;
+        }
+
+    b1->peer    = bio2;
+    b2->peer    = bio1;
+    b1->role    = 0;
+    b2->role    = 1;
+    bio1->init  = 1;
+    bio2->init  = 1;
+    return 1;
+}
+
+/* BIO_destroy_bio_pair (BIO_C_DESTROY_BIO_PAIR) */
+static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1)
+{
+    BIO *bio2;
+    struct bio_dgram_pair_st *b1 = bio1->ptr, *b2;
+
+    ring_buf_destroy(&b1->rbuf);
+    bio1->init = 0;
+
+    /* Early return if we don't have a peer. */
+    if (b1->peer == NULL)
+        return 1;
+
+    bio2 = b1->peer;
+    b2 = bio2->ptr;
+
+    /* Invariant. */
+    if (!ossl_assert(b2->peer == bio1))
+        return 0;
+
+    /* Free buffers. */
+    ring_buf_destroy(&b2->rbuf);
+
+    bio2->init = 0;
+    b1->peer = NULL;
+    b2->peer = NULL;
+    return 1;
+}
+
+/* BIO_eof (BIO_CTRL_EOF) */
+static int dgram_pair_ctrl_eof(BIO *bio)
+{
+    struct bio_dgram_pair_st *b = bio->ptr, *peerb;
+
+    if (!ossl_assert(b != NULL))
+        return -1;
+
+    /* If we aren't initialized, we can never read anything */
+    if (!bio->init)
+        return 1;
+    if (!is_dgram_pair(b))
+        return 0;
+
+
+    peerb = b->peer->ptr;
+    if (!ossl_assert(peerb != NULL))
+        return -1;
+
+    /*
+     * Since we are emulating datagram semantics, never indicate EOF so long as
+     * we have a peer.
+     */
+    return 0;
+}
+
+/* BIO_set_write_buf_size (BIO_C_SET_WRITE_BUF_SIZE) */
+static int dgram_pair_ctrl_set_write_buf_size(BIO *bio, size_t len)
+{
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    /* Changing buffer sizes is not permitted while a peer is connected. */
+    if (b->peer != NULL) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE);
+        return 0;
+    }
+
+    /* Enforce minimum size. */
+    if (len < MIN_BUF_LEN)
+        len = MIN_BUF_LEN;
+
+    if (b->rbuf.start != NULL) {
+        if (!ring_buf_resize(&b->rbuf, len))
+            return 0;
+    }
+
+    b->req_buf_len = len;
+    b->grows_on_write = 0;
+    return 1;
+}
+
+/* BIO_reset (BIO_CTRL_RESET) */
+static int dgram_pair_ctrl_reset(BIO *bio)
+{
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    ring_buf_clear(&b->rbuf);
+    return 1;
+}
+
+/* BIO_pending (BIO_CTRL_PENDING) (Threadsafe) */
+static size_t dgram_pair_ctrl_pending(BIO *bio)
+{
+    size_t saved_idx, saved_count;
+    struct bio_dgram_pair_st *b = bio->ptr, *readb;
+    struct dgram_hdr hdr;
+    size_t l;
+
+    /* Safe to check; init may not change during this call */
+    if (!bio->init)
+        return 0;
+    if (is_dgram_pair(b))
+        readb = b->peer->ptr;
+    else
+        readb = b;
+
+    if (CRYPTO_THREAD_write_lock(readb->lock) == 0)
+        return 0;
+
+    saved_idx   = readb->rbuf.idx[1];
+    saved_count = readb->rbuf.count;
+
+    l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr));
+
+    readb->rbuf.idx[1] = saved_idx;
+    readb->rbuf.count  = saved_count;
+
+    CRYPTO_THREAD_unlock(readb->lock);
+
+    if (!ossl_assert(l == 0 || l == sizeof(hdr)))
+        return 0;
+
+    return l > 0 ? hdr.len : 0;
+}
+
+/* BIO_get_write_guarantee (BIO_C_GET_WRITE_GUARANTEE) (Threadsafe) */
+static size_t dgram_pair_ctrl_get_write_guarantee(BIO *bio)
+{
+    size_t l;
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    if (CRYPTO_THREAD_read_lock(b->lock) == 0)
+        return 0;
+
+    l = b->rbuf.len - b->rbuf.count;
+    if (l >= sizeof(struct dgram_hdr))
+        l -= sizeof(struct dgram_hdr);
+
+    /*
+     * If the amount of buffer space would not be enough to accommodate the
+     * worst-case size of a datagram, report no space available.
+     */
+    if (l < b->mtu)
+        l = 0;
+
+    CRYPTO_THREAD_unlock(b->lock);
+    return l;
+}
+
+/* BIO_dgram_get_local_addr_cap (BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP) */
+static int dgram_pair_ctrl_get_local_addr_cap(BIO *bio)
+{
+    struct bio_dgram_pair_st *b = bio->ptr, *readb;
+
+    if (!bio->init)
+        return 0;
+
+    if (is_dgram_pair(b))
+        readb = b->peer->ptr;
+    else
+        readb = b;
+
+    return (~readb->cap & (BIO_DGRAM_CAP_HANDLES_SRC_ADDR
+                           | BIO_DGRAM_CAP_PROVIDES_DST_ADDR)) == 0;
+}
+
+/* BIO_dgram_get_effective_caps (BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS) */
+static int dgram_pair_ctrl_get_effective_caps(BIO *bio)
+{
+    struct bio_dgram_pair_st *b = bio->ptr, *peerb;
+
+    if (b->peer == NULL)
+        return 0;
+
+    peerb = b->peer->ptr;
+
+    return peerb->cap;
+}
+
+/* BIO_dgram_get_caps (BIO_CTRL_DGRAM_GET_CAPS) */
+static uint32_t dgram_pair_ctrl_get_caps(BIO *bio)
+{
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    return b->cap;
+}
+
+/* BIO_dgram_set_caps (BIO_CTRL_DGRAM_SET_CAPS) */
+static int dgram_pair_ctrl_set_caps(BIO *bio, uint32_t caps)
+{
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    b->cap = caps;
+    return 1;
+}
+
+/* BIO_dgram_get_local_addr_enable (BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE) */
+static int dgram_pair_ctrl_get_local_addr_enable(BIO *bio)
+{
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    return b->local_addr_enable;
+}
+
+/* BIO_dgram_set_local_addr_enable (BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE) */
+static int dgram_pair_ctrl_set_local_addr_enable(BIO *bio, int enable)
+{
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    if (dgram_pair_ctrl_get_local_addr_cap(bio) == 0)
+        return 0;
+
+    b->local_addr_enable = (enable != 0 ? 1 : 0);
+    return 1;
+}
+
+/* BIO_dgram_get_mtu (BIO_CTRL_DGRAM_GET_MTU) */
+static int dgram_pair_ctrl_get_mtu(BIO *bio)
+{
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    return b->mtu;
+}
+
+/* BIO_dgram_set_mtu (BIO_CTRL_DGRAM_SET_MTU) */
+static int dgram_pair_ctrl_set_mtu(BIO *bio, size_t mtu)
+{
+    struct bio_dgram_pair_st *b = bio->ptr, *peerb;
+
+    b->mtu = mtu;
+
+    if (b->peer != NULL) {
+        peerb = b->peer->ptr;
+        peerb->mtu = mtu;
+    }
+
+    return 1;
+}
+
+/* Partially threadsafe (some commands) */
+static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    if (!ossl_assert(b != NULL))
+        return 0;
+
+    switch (cmd) {
+    /*
+     * BIO_set_write_buf_size: Set the size of the ring buffer used for storing
+     * datagrams. No more writes can be performed once the buffer is filled up,
+     * until reads are performed. This cannot be used after a peer is connected.
+     */
+    case BIO_C_SET_WRITE_BUF_SIZE: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_set_write_buf_size(bio, (size_t)num);
+        break;
+
+    /*
+     * BIO_get_write_buf_size: Get ring buffer size.
+     */
+    case BIO_C_GET_WRITE_BUF_SIZE: /* Non-threadsafe */
+        ret = (long)b->req_buf_len;
+        break;
+
+    /*
+     * BIO_reset: Clear all data which was written to this side of the pair.
+     */
+    case BIO_CTRL_RESET: /* Non-threadsafe */
+        dgram_pair_ctrl_reset(bio);
+        break;
+
+    /*
+     * BIO_get_write_guarantee: Any BIO_write providing a buffer less than or
+     * equal to this value is guaranteed to succeed.
+     */
+    case BIO_C_GET_WRITE_GUARANTEE: /* Threadsafe */
+        ret = (long)dgram_pair_ctrl_get_write_guarantee(bio);
+        break;
+
+    /* BIO_pending: Bytes available to read. */
+    case BIO_CTRL_PENDING: /* Threadsafe */
+        ret = (long)dgram_pair_ctrl_pending(bio);
+        break;
+
+    /* BIO_flush: No-op. */
+    case BIO_CTRL_FLUSH: /* Threadsafe */
+        break;
+
+    /* BIO_dgram_get_no_trunc */
+    case BIO_CTRL_DGRAM_GET_NO_TRUNC: /* Non-threadsafe */
+        ret = (long)b->no_trunc;
+        break;
+
+    /* BIO_dgram_set_no_trunc */
+    case BIO_CTRL_DGRAM_SET_NO_TRUNC: /* Non-threadsafe */
+        b->no_trunc = (num > 0);
+        break;
+
+    /* BIO_dgram_get_local_addr_enable */
+    case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE: /* Non-threadsafe */
+        *(int *)ptr = (int)dgram_pair_ctrl_get_local_addr_enable(bio);
+        break;
+
+    /* BIO_dgram_set_local_addr_enable */
+    case BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_set_local_addr_enable(bio, num);
+        break;
+
+    /* BIO_dgram_get_local_addr_cap: Can local addresses be supported? */
+    case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_get_local_addr_cap(bio);
+        break;
+
+    /* BIO_dgram_get_effective_caps */
+    case BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS: /* Non-threadsafe */
+    /* BIO_dgram_get_caps */
+    case BIO_CTRL_DGRAM_GET_CAPS: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_get_caps(bio);
+        break;
+
+    /* BIO_dgram_set_caps */
+    case BIO_CTRL_DGRAM_SET_CAPS: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_set_caps(bio, (uint32_t)num);
+        break;
+
+    /* BIO_dgram_get_mtu */
+    case BIO_CTRL_DGRAM_GET_MTU: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_get_mtu(bio);
+        break;
+
+    /* BIO_dgram_set_mtu */
+    case BIO_CTRL_DGRAM_SET_MTU: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_set_mtu(bio, (uint32_t)num);
+        break;
+
+    /*
+     * BIO_eof: Returns whether this half of the BIO pair is empty of data to
+     * read.
+     */
+    case BIO_CTRL_EOF: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_eof(bio);
+        break;
+
+    default:
+        ret = 0;
+        break;
+    }
+
+    return ret;
+}
+
+static long dgram_pair_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+
+    switch (cmd) {
+    /*
+     * BIO_make_bio_pair: this is usually used by BIO_new_dgram_pair, though it
+     * may be used manually after manually creating each half of a BIO pair
+     * using BIO_new. This only needs to be called on one of the BIOs.
+     */
+    case BIO_C_MAKE_BIO_PAIR: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_make_bio_pair(bio, (BIO *)ptr);
+        break;
+
+    /*
+     * BIO_destroy_bio_pair: Manually disconnect two halves of a BIO pair so
+     * that they are no longer peers.
+     */
+    case BIO_C_DESTROY_BIO_PAIR: /* Non-threadsafe */
+        dgram_pair_ctrl_destroy_bio_pair(bio);
+        break;
+
+    /* BIO_dgram_get_effective_caps */
+    case BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS: /* Non-threadsafe */
+        ret = (long)dgram_pair_ctrl_get_effective_caps(bio);
+        break;
+
+    default:
+        ret = dgram_mem_ctrl(bio, cmd, num, ptr);
+        break;
+    }
+
+    return ret;
+}
+
+int BIO_new_bio_dgram_pair(BIO **pbio1, size_t writebuf1,
+                           BIO **pbio2, size_t writebuf2)
+{
+    int ret = 0;
+    long r;
+    BIO *bio1 = NULL, *bio2 = NULL;
+
+    bio1 = BIO_new(BIO_s_dgram_pair());
+    if (bio1 == NULL)
+        goto err;
+
+    bio2 = BIO_new(BIO_s_dgram_pair());
+    if (bio2 == NULL)
+        goto err;
+
+    if (writebuf1 > 0) {
+        r = BIO_set_write_buf_size(bio1, writebuf1);
+        if (r == 0)
+            goto err;
+    }
+
+    if (writebuf2 > 0) {
+        r = BIO_set_write_buf_size(bio2, writebuf2);
+        if (r == 0)
+            goto err;
+    }
+
+    r = BIO_make_bio_pair(bio1, bio2);
+    if (r == 0)
+        goto err;
+
+    ret = 1;
+err:
+    if (ret == 0) {
+        BIO_free(bio1);
+        bio1 = NULL;
+        BIO_free(bio2);
+        bio2 = NULL;
+    }
+
+    *pbio1 = bio1;
+    *pbio2 = bio2;
+    return ret;
+}
+
+/* Must hold peer write lock */
+static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf, size_t sz)
+{
+    size_t total_read = 0;
+
+    /*
+     * We repeat pops from the ring buffer for as long as we have more
+     * application *buffer to fill until we fail. We may not be able to pop
+     * enough data to fill the buffer in one operation if the ring buffer wraps
+     * around, but there may still be more data available.
+     */
+    while (sz > 0) {
+        uint8_t *src_buf = NULL;
+        size_t src_len = 0;
+
+        /*
+         * There are two BIO instances, each with a ringbuf. We read from the
+         * peer ringbuf and write to our own ringbuf.
+         */
+        ring_buf_tail(&b->rbuf, &src_buf, &src_len);
+        if (src_len == 0)
+            break;
+
+        if (src_len > sz)
+            src_len = sz;
+
+        if (buf != NULL)
+            memcpy(buf, src_buf, src_len);
+
+        ring_buf_pop(&b->rbuf, src_len);
+
+        if (buf != NULL)
+            buf += src_len;
+        total_read  += src_len;
+        sz          -= src_len;
+    }
+
+    return total_read;
+}
+
+/*
+ * Must hold peer write lock. Returns number of bytes processed or negated BIO
+ * response code.
+ */
+static ossl_ssize_t dgram_pair_read_actual(BIO *bio, char *buf, size_t sz,
+                                           BIO_ADDR *local, BIO_ADDR *peer,
+                                           int is_multi)
+{
+    size_t l, trunc = 0, saved_idx, saved_count;
+    struct bio_dgram_pair_st *b = bio->ptr, *readb;
+    struct dgram_hdr hdr;
+
+    if (!is_multi)
+        BIO_clear_retry_flags(bio);
+
+    if (!bio->init)
+        return -BIO_R_UNINITIALIZED;
+
+    if (!ossl_assert(b != NULL))
+        return -BIO_R_TRANSFER_ERROR;
+
+    if (is_dgram_pair(b))
+        readb = b->peer->ptr;
+    else
+        readb = b;
+    if (!ossl_assert(readb != NULL && readb->rbuf.start != NULL))
+        return -BIO_R_TRANSFER_ERROR;
+
+    if (sz > 0 && buf == NULL)
+        return -BIO_R_INVALID_ARGUMENT;
+
+    /* If the caller wants to know the local address, it must be enabled */
+    if (local != NULL && b->local_addr_enable == 0)
+        return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE;
+
+    /* Read the header. */
+    saved_idx   = readb->rbuf.idx[1];
+    saved_count = readb->rbuf.count;
+    l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr));
+    if (l == 0) {
+        /* Buffer was empty. */
+        if (!is_multi)
+            BIO_set_retry_read(bio);
+        return -BIO_R_NON_FATAL;
+    }
+
+    if (!ossl_assert(l == sizeof(hdr)))
+        /*
+         * This should not be possible as headers (and their following payloads)
+         * should always be written atomically.
+         */
+        return -BIO_R_BROKEN_PIPE;
+
+    if (sz > hdr.len) {
+        sz = hdr.len;
+    } else if (sz < hdr.len) {
+        /* Truncation is occurring. */
+        trunc = hdr.len - sz;
+        if (b->no_trunc) {
+            /* Restore original state. */
+            readb->rbuf.idx[1] = saved_idx;
+            readb->rbuf.count  = saved_count;
+            return -BIO_R_NON_FATAL;
+        }
+    }
+
+    l = dgram_pair_read_inner(readb, (uint8_t *)buf, sz);
+    if (!ossl_assert(l == sz))
+        /* We were somehow not able to read the entire datagram. */
+        return -BIO_R_TRANSFER_ERROR;
+
+    /*
+     * If the datagram was truncated due to an inadequate buffer, discard the
+     * remainder.
+     */
+    if (trunc > 0 && !ossl_assert(dgram_pair_read_inner(readb, NULL, trunc) == trunc))
+        /* We were somehow not able to read/skip the entire datagram. */
+        return -BIO_R_TRANSFER_ERROR;
+
+    if (local != NULL)
+        *local = hdr.dst_addr;
+    if (peer != NULL)
+        *peer  = hdr.src_addr;
+
+    return (ossl_ssize_t)l;
+}
+
+/* Threadsafe */
+static int dgram_pair_lock_both_write(struct bio_dgram_pair_st *a,
+                                      struct bio_dgram_pair_st *b)
+{
+    struct bio_dgram_pair_st *x, *y;
+
+    x = (a->role == 1) ? a : b;
+    y = (a->role == 1) ? b : a;
+
+    if (!ossl_assert(a->role != b->role))
+        return 0;
+
+    if (!ossl_assert(a != b && x != y))
+        return 0;
+
+    if (CRYPTO_THREAD_write_lock(x->lock) == 0)
+        return 0;
+
+    if (CRYPTO_THREAD_write_lock(y->lock) == 0) {
+        CRYPTO_THREAD_unlock(x->lock);
+        return 0;
+    }
+
+    return 1;
+}
+
+static void dgram_pair_unlock_both(struct bio_dgram_pair_st *a,
+                                   struct bio_dgram_pair_st *b)
+{
+    CRYPTO_THREAD_unlock(a->lock);
+    CRYPTO_THREAD_unlock(b->lock);
+}
+
+/* Threadsafe */
+static int dgram_pair_read(BIO *bio, char *buf, int sz_)
+{
+    int ret;
+    ossl_ssize_t l;
+    struct bio_dgram_pair_st *b = bio->ptr, *peerb;
+
+    if (sz_ < 0) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
+        return -1;
+    }
+
+    if (b->peer == NULL) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
+        return -1;
+    }
+
+    peerb = b->peer->ptr;
+
+    /*
+     * For BIO_read we have to acquire both locks because we touch the retry
+     * flags on the local bio. (This is avoided in the recvmmsg case as it does
+     * not touch the retry flags.)
+     */
+    if (dgram_pair_lock_both_write(peerb, b) == 0) {
+        ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
+        return -1;
+    }
+
+    l = dgram_pair_read_actual(bio, buf, (size_t)sz_, NULL, NULL, 0);
+    if (l < 0) {
+        if (l != -BIO_R_NON_FATAL)
+            ERR_raise(ERR_LIB_BIO, -l);
+        ret = -1;
+    } else {
+        ret = (int)l;
+    }
+
+    dgram_pair_unlock_both(peerb, b);
+    return ret;
+}
+
+/* Threadsafe */
+static int dgram_pair_recvmmsg(BIO *bio, BIO_MSG *msg,
+                               size_t stride, size_t num_msg,
+                               uint64_t flags,
+                               size_t *num_processed)
+{
+    int ret;
+    ossl_ssize_t l;
+    BIO_MSG *m;
+    size_t i;
+    struct bio_dgram_pair_st *b = bio->ptr, *readb;
+
+    if (num_msg == 0) {
+        *num_processed = 0;
+        return 1;
+    }
+
+    if (!bio->init) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
+        *num_processed = 0;
+        return 0;
+    }
+
+    if (is_dgram_pair(b))
+        readb = b->peer->ptr;
+    else
+        readb = b;
+
+    if (CRYPTO_THREAD_write_lock(readb->lock) == 0) {
+        ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
+        *num_processed = 0;
+        return 0;
+    }
+
+    for (i = 0; i < num_msg; ++i) {
+        m = &BIO_MSG_N(msg, i);
+        l = dgram_pair_read_actual(bio, m->data, m->data_len,
+                                   m->local, m->peer, 1);
+        if (l < 0) {
+            *num_processed = i;
+            if (i > 0) {
+                ret = 1;
+            } else {
+                ERR_raise(ERR_LIB_BIO, -l);
+                ret = 0;
+            }
+            goto out;
+        }
+
+        m->data_len = l;
+        m->flags    = 0;
+    }
+
+    *num_processed = i;
+    ret = 1;
+out:
+    CRYPTO_THREAD_unlock(readb->lock);
+    return ret;
+}
+
+/* Threadsafe */
+static int dgram_mem_read(BIO *bio, char *buf, int sz_)
+{
+    int ret;
+    ossl_ssize_t l;
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    if (sz_ < 0) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
+        return -1;
+    }
+
+    if (CRYPTO_THREAD_write_lock(b->lock) == 0) {
+        ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
+        return -1;
+    }
+
+    l = dgram_pair_read_actual(bio, buf, (size_t)sz_, NULL, NULL, 0);
+    if (l < 0) {
+        if (l != -BIO_R_NON_FATAL)
+            ERR_raise(ERR_LIB_BIO, -l);
+        ret = -1;
+    } else {
+        ret = (int)l;
+    }
+
+    CRYPTO_THREAD_unlock(b->lock);
+    return ret;
+}
+
+/*
+ * Calculate the array growth based on the target size.
+ *
+ * The growth factor is a rational number and is defined by a numerator
+ * and a denominator.  According to Andrew Koenig in his paper "Why Are
+ * Vectors Efficient?" from JOOP 11(5) 1998, this factor should be less
+ * than the golden ratio (1.618...).
+ *
+ * We use an expansion factor of 8 / 5 = 1.6
+ */
+static const size_t max_rbuf_size = SIZE_MAX / 2; /* unlimited in practice */
+static ossl_inline size_t compute_rbuf_growth(size_t target, size_t current)
+{
+    int err = 0;
+
+    while (current < target) {
+        if (current >= max_rbuf_size)
+            return 0;
+
+        current = safe_muldiv_size_t(current, 8, 5, &err);
+        if (err)
+            return 0;
+        if (current >= max_rbuf_size)
+            current = max_rbuf_size;
+    }
+    return current;
+}
+
+/* Must hold local write lock */
+static size_t dgram_pair_write_inner(struct bio_dgram_pair_st *b,
+                                     const uint8_t *buf, size_t sz)
+{
+    size_t total_written = 0;
+
+    /*
+     * We repeat pushes to the ring buffer for as long as we have data until we
+     * fail. We may not be able to push in one operation if the ring buffer
+     * wraps around, but there may still be more room for data.
+     */
+    while (sz > 0) {
+        size_t dst_len;
+        uint8_t *dst_buf;
+
+        /*
+         * There are two BIO instances, each with a ringbuf. We write to our own
+         * ringbuf and read from the peer ringbuf.
+         */
+        ring_buf_head(&b->rbuf, &dst_buf, &dst_len);
+        if (dst_len == 0) {
+            size_t new_len;
+
+            if (!b->grows_on_write) /* resize only if size not set explicitly */
+                break;
+            /* increase the size */
+            new_len = compute_rbuf_growth(b->req_buf_len + sz, b->req_buf_len);
+            if (new_len == 0 || !ring_buf_resize(&b->rbuf, new_len))
+                break;
+            b->req_buf_len = new_len;
+        }
+
+        if (dst_len > sz)
+            dst_len = sz;
+
+        memcpy(dst_buf, buf, dst_len);
+        ring_buf_push(&b->rbuf, dst_len);
+
+        buf             += dst_len;
+        sz              -= dst_len;
+        total_written   += dst_len;
+    }
+
+    return total_written;
+}
+
+/*
+ * Must hold local write lock. Returns number of bytes processed or negated BIO
+ * response code.
+ */
+static ossl_ssize_t dgram_pair_write_actual(BIO *bio, const char *buf, size_t sz,
+                                            const BIO_ADDR *local, const BIO_ADDR *peer,
+                                            int is_multi)
+{
+    static const BIO_ADDR zero_addr;
+    size_t saved_idx, saved_count;
+    struct bio_dgram_pair_st *b = bio->ptr, *readb;
+    struct dgram_hdr hdr = {0};
+
+    if (!is_multi)
+        BIO_clear_retry_flags(bio);
+
+    if (!bio->init)
+        return -BIO_R_UNINITIALIZED;
+
+    if (!ossl_assert(b != NULL && b->rbuf.start != NULL))
+        return -BIO_R_TRANSFER_ERROR;
+
+    if (sz > 0 && buf == NULL)
+        return -BIO_R_INVALID_ARGUMENT;
+
+    if (local != NULL && b->local_addr_enable == 0)
+        return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE;
+
+    if (is_dgram_pair(b))
+        readb = b->peer->ptr;
+    else
+        readb = b;
+    if (peer != NULL && (readb->cap & BIO_DGRAM_CAP_HANDLES_DST_ADDR) == 0)
+        return -BIO_R_PEER_ADDR_NOT_AVAILABLE;
+
+    hdr.len = sz;
+    hdr.dst_addr = (peer != NULL ? *peer : zero_addr);
+    hdr.src_addr = (local != NULL ? *local : zero_addr);
+
+    saved_idx   = b->rbuf.idx[0];
+    saved_count = b->rbuf.count;
+    if (dgram_pair_write_inner(b, (const uint8_t *)&hdr, sizeof(hdr)) != sizeof(hdr)
+            || dgram_pair_write_inner(b, (const uint8_t *)buf, sz) != sz) {
+        /*
+         * We were not able to push the header and the entirety of the payload
+         * onto the ring buffer, so abort and roll back the ring buffer state.
+         */
+        b->rbuf.idx[0] = saved_idx;
+        b->rbuf.count  = saved_count;
+        if (!is_multi)
+            BIO_set_retry_write(bio);
+        return -BIO_R_NON_FATAL;
+    }
+
+    return sz;
+}
+
+/* Threadsafe */
+static int dgram_pair_write(BIO *bio, const char *buf, int sz_)
+{
+    int ret;
+    ossl_ssize_t l;
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    if (sz_ < 0) {
+        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
+        return -1;
+    }
+
+    if (CRYPTO_THREAD_write_lock(b->lock) == 0) {
+        ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
+        return -1;
+    }
+
+    l = dgram_pair_write_actual(bio, buf, (size_t)sz_, NULL, NULL, 0);
+    if (l < 0) {
+        ERR_raise(ERR_LIB_BIO, -l);
+        ret = -1;
+    } else {
+        ret = (int)l;
+    }
+
+    CRYPTO_THREAD_unlock(b->lock);
+    return ret;
+}
+
+/* Threadsafe */
+static int dgram_pair_sendmmsg(BIO *bio, BIO_MSG *msg,
+                               size_t stride, size_t num_msg,
+                               uint64_t flags, size_t *num_processed)
+{
+    ossl_ssize_t ret, l;
+    BIO_MSG *m;
+    size_t i;
+    struct bio_dgram_pair_st *b = bio->ptr;
+
+    if (num_msg == 0) {
+        *num_processed = 0;
+        return 1;
+    }
+
+    if (CRYPTO_THREAD_write_lock(b->lock) == 0) {
+        ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
+        *num_processed = 0;
+        return 0;
+    }
+
+    for (i = 0; i < num_msg; ++i) {
+        m = &BIO_MSG_N(msg, i);
+        l = dgram_pair_write_actual(bio, m->data, m->data_len,
+                                    m->local, m->peer, 1);
+        if (l < 0) {
+            *num_processed = i;
+            if (i > 0) {
+                ret = 1;
+            } else {
+                ERR_raise(ERR_LIB_BIO, -l);
+                ret = 0;
+            }
+            goto out;
+        }
+
+        m->flags = 0;
+    }
+
+    *num_processed = i;
+    ret = 1;
+out:
+    CRYPTO_THREAD_unlock(b->lock);
+    return ret;
+}
+
+#endif

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 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

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 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

+ 4 - 4
libs/openssl/crypto/bio/bss_log.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 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,8 @@
 
 #if defined(OPENSSL_SYS_WINCE)
 #elif defined(OPENSSL_SYS_WIN32)
+#elif defined(__wasi__)
+# define NO_SYSLOG
 #elif defined(OPENSSL_SYS_VMS)
 # include <opcdef.h>
 # include <descrip.h>
@@ -197,10 +199,8 @@ static int slg_write(BIO *b, const char *in, int inl)
 
     if (inl < 0)
         return 0;
-    if ((buf = OPENSSL_malloc(inl + 1)) == NULL) {
-        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+    if ((buf = OPENSSL_malloc(inl + 1)) == NULL)
         return 0;
-    }
     memcpy(buf, in, inl);
     buf[inl] = '\0';
 

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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

+ 77 - 5
libs/openssl/crypto/bio/bss_sock.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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 <stdio.h>
 #include <errno.h>
 #include "bio_local.h"
+#include "internal/bio_tfo.h"
 #include "internal/cryptlib.h"
 #include "internal/ktls.h"
 
@@ -27,6 +28,14 @@
 #  define sock_puts  SockPuts
 # endif
 
+struct bss_sock_st {
+    BIO_ADDR tfo_peer;
+    int tfo_first;
+#ifndef OPENSSL_NO_KTLS
+    unsigned char ktls_record_type;
+#endif
+};
+
 static int sock_write(BIO *h, const char *buf, int num);
 static int sock_read(BIO *h, char *buf, int size);
 static int sock_puts(BIO *h, const char *str);
@@ -81,8 +90,10 @@ static int sock_new(BIO *bi)
 {
     bi->init = 0;
     bi->num = 0;
-    bi->ptr = NULL;
     bi->flags = 0;
+    bi->ptr = OPENSSL_zalloc(sizeof(struct bss_sock_st));
+    if (bi->ptr == NULL)
+        return 0;
     return 1;
 }
 
@@ -97,6 +108,8 @@ static int sock_free(BIO *a)
         a->init = 0;
         a->flags = 0;
     }
+    OPENSSL_free(a->ptr);
+    a->ptr = NULL;
     return 1;
 }
 
@@ -126,17 +139,30 @@ static int sock_read(BIO *b, char *out, int outl)
 static int sock_write(BIO *b, const char *in, int inl)
 {
     int ret = 0;
+# if !defined(OPENSSL_NO_KTLS) || defined(OSSL_TFO_SENDTO)
+    struct bss_sock_st *data = (struct bss_sock_st *)b->ptr;
+# endif
 
     clear_socket_error();
 # ifndef OPENSSL_NO_KTLS
     if (BIO_should_ktls_ctrl_msg_flag(b)) {
-        unsigned char record_type = (intptr_t)b->ptr;
+        unsigned char record_type = data->ktls_record_type;
         ret = ktls_send_ctrl_message(b->num, record_type, in, inl);
         if (ret >= 0) {
             ret = inl;
             BIO_clear_ktls_ctrl_msg_flag(b);
         }
     } else
+# endif
+# if defined(OSSL_TFO_SENDTO)
+    if (data->tfo_first) {
+        struct bss_sock_st *data = (struct bss_sock_st *)b->ptr;
+        socklen_t peerlen = BIO_ADDR_sockaddr_size(&data->tfo_peer);
+
+        ret = sendto(b->num, in, inl, OSSL_TFO_SENDTO,
+                     BIO_ADDR_sockaddr(&data->tfo_peer), peerlen);
+        data->tfo_first = 0;
+    } else
 # endif
         ret = writesocket(b->num, in, inl);
     BIO_clear_retry_flags(b);
@@ -151,16 +177,24 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
 {
     long ret = 1;
     int *ip;
+    struct bss_sock_st *data = (struct bss_sock_st *)b->ptr;
 # ifndef OPENSSL_NO_KTLS
     ktls_crypto_info_t *crypto_info;
 # endif
 
     switch (cmd) {
     case BIO_C_SET_FD:
-        sock_free(b);
+        /* minimal sock_free() */
+        if (b->shutdown) {
+            if (b->init)
+                BIO_closesocket(b->num);
+            b->flags = 0;
+        }
         b->num = *((int *)ptr);
         b->shutdown = (int)num;
         b->init = 1;
+        data->tfo_first = 0;
+        memset(&data->tfo_peer, 0, sizeof(data->tfo_peer));
         break;
     case BIO_C_GET_FD:
         if (b->init) {
@@ -181,6 +215,20 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
     case BIO_CTRL_FLUSH:
         ret = 1;
         break;
+    case BIO_CTRL_GET_RPOLL_DESCRIPTOR:
+    case BIO_CTRL_GET_WPOLL_DESCRIPTOR:
+        {
+            BIO_POLL_DESCRIPTOR *pd = ptr;
+
+            if (!b->init) {
+                ret = 0;
+                break;
+            }
+
+            pd->type        = BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD;
+            pd->value.fd    = b->num;
+        }
+        break;
 # ifndef OPENSSL_NO_KTLS
     case BIO_CTRL_SET_KTLS:
         crypto_info = (ktls_crypto_info_t *)ptr;
@@ -194,17 +242,41 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
         return BIO_should_ktls_flag(b, 0) != 0;
     case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
         BIO_set_ktls_ctrl_msg_flag(b);
-        b->ptr = (void *)num;
+        data->ktls_record_type = (unsigned char)num;
         ret = 0;
         break;
     case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
         BIO_clear_ktls_ctrl_msg_flag(b);
         ret = 0;
         break;
+    case BIO_CTRL_SET_KTLS_TX_ZEROCOPY_SENDFILE:
+        ret = ktls_enable_tx_zerocopy_sendfile(b->num);
+        if (ret)
+            BIO_set_ktls_zerocopy_sendfile_flag(b);
+        break;
 # endif
     case BIO_CTRL_EOF:
         ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
         break;
+    case BIO_C_GET_CONNECT:
+        if (ptr != NULL && num == 2) {
+            const char **pptr = (const char **)ptr;
+
+            *pptr = (const char *)&data->tfo_peer;
+        } else {
+            ret = 0;
+        }
+        break;
+    case BIO_C_SET_CONNECT:
+        if (ptr != NULL && num == 2) {
+            ret = BIO_ADDR_make(&data->tfo_peer,
+                                BIO_ADDR_sockaddr((const BIO_ADDR *)ptr));
+            if (ret)
+                data->tfo_first = 1;
+        } else {
+            ret = 0;
+        }
+        break;
     default:
         ret = 0;
         break;

+ 5 - 7
libs/openssl/crypto/bio/ossl_core_bio.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2021-2023 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,7 +17,6 @@
  */
 struct ossl_core_bio_st {
     CRYPTO_REF_COUNT ref_cnt;
-    CRYPTO_RWLOCK *ref_lock;
     BIO *bio;
 };
 
@@ -25,11 +24,10 @@ static OSSL_CORE_BIO *core_bio_new(void)
 {
     OSSL_CORE_BIO *cb = OPENSSL_malloc(sizeof(*cb));
 
-    if (cb == NULL || (cb->ref_lock = CRYPTO_THREAD_lock_new()) == NULL) {
+    if (cb == NULL || !CRYPTO_NEW_REF(&cb->ref_cnt, 1)) {
         OPENSSL_free(cb);
         return NULL;
     }
-    cb->ref_cnt = 1;
     return cb;
 }
 
@@ -37,7 +35,7 @@ int ossl_core_bio_up_ref(OSSL_CORE_BIO *cb)
 {
     int ref = 0;
 
-    return CRYPTO_UP_REF(&cb->ref_cnt, &ref, cb->ref_lock);
+    return CRYPTO_UP_REF(&cb->ref_cnt, &ref);
 }
 
 int ossl_core_bio_free(OSSL_CORE_BIO *cb)
@@ -45,10 +43,10 @@ int ossl_core_bio_free(OSSL_CORE_BIO *cb)
     int ref = 0, res = 1;
 
     if (cb != NULL) {
-        CRYPTO_DOWN_REF(&cb->ref_cnt, &ref, cb->ref_lock);
+        CRYPTO_DOWN_REF(&cb->ref_cnt, &ref);
         if (ref <= 0) {
             res = BIO_free(cb->bio);
-            CRYPTO_THREAD_lock_free(cb->ref_lock);
+            CRYPTO_FREE_REF(&cb->ref_cnt);
             OPENSSL_free(cb);
         }
     }

+ 2 - 4
libs/openssl/crypto/bn/bn_blind.c

@@ -33,14 +33,12 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
 
     bn_check_top(mod);
 
-    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
         return NULL;
-    }
 
     ret->lock = CRYPTO_THREAD_lock_new();
     if (ret->lock == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_BN, ERR_R_CRYPTO_LIB);
         OPENSSL_free(ret);
         return NULL;
     }

+ 1 - 1
libs/openssl/crypto/bn/bn_const.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2021 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

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

@@ -23,10 +23,8 @@ char *BN_bn2hex(const BIGNUM *a)
     if (BN_is_zero(a))
         return OPENSSL_strdup("0");
     buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
-    if (buf == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (buf == NULL)
         goto err;
-    }
     p = buf;
     if (a->neg)
         *p++ = '-';
@@ -70,10 +68,8 @@ char *BN_bn2dec(const BIGNUM *a)
     bn_data_num = num / BN_DEC_NUM + 1;
     bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG));
     buf = OPENSSL_malloc(tbytes);
-    if (buf == NULL || bn_data == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (buf == NULL || bn_data == NULL)
         goto err;
-    }
     if ((t = BN_dup(a)) == NULL)
         goto err;
 

+ 3 - 9
libs/openssl/crypto/bn/bn_ctx.c

@@ -119,10 +119,8 @@ BN_CTX *BN_CTX_new_ex(OSSL_LIB_CTX *ctx)
 {
     BN_CTX *ret;
 
-    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
         return NULL;
-    }
     /* Initialise the structure */
     BN_POOL_init(&ret->pool);
     BN_STACK_init(&ret->stack);
@@ -268,10 +266,8 @@ static int BN_STACK_push(BN_STACK *st, unsigned int idx)
             st->size ? (st->size * 3 / 2) : BN_CTX_START_FRAMES;
         unsigned int *newitems;
 
-        if ((newitems = OPENSSL_malloc(sizeof(*newitems) * newsize)) == NULL) {
-            ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+        if ((newitems = OPENSSL_malloc(sizeof(*newitems) * newsize)) == NULL)
             return 0;
-        }
         if (st->depth)
             memcpy(newitems, st->indexes, sizeof(*newitems) * st->depth);
         OPENSSL_free(st->indexes);
@@ -322,10 +318,8 @@ static BIGNUM *BN_POOL_get(BN_POOL *p, int flag)
     if (p->used == p->size) {
         BN_POOL_ITEM *item;
 
-        if ((item = OPENSSL_malloc(sizeof(*item))) == NULL) {
-            ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+        if ((item = OPENSSL_malloc(sizeof(*item))) == NULL)
             return NULL;
-        }
         for (loop = 0, bn = item->vals; loop++ < BN_CTX_POOL_SIZE; bn++) {
             bn_init(bn);
             if ((flag & BN_FLG_SECURE) != 0)

+ 30 - 9
libs/openssl/crypto/bn/bn_exp.c

@@ -169,7 +169,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
 int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                     const BIGNUM *m, BN_CTX *ctx)
 {
-    int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+    int i, j, bits, ret = 0, wstart, wend, window;
     int start = 1;
     BIGNUM *aa;
     /* Table of variables obtained from 'ctx' */
@@ -239,14 +239,23 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
     start = 1;                  /* This is used to avoid multiplication etc
                                  * when there is only the value '1' in the
                                  * buffer. */
-    wvalue = 0;                 /* The 'value' of the window */
     wstart = bits - 1;          /* The top bit of the window */
     wend = 0;                   /* The bottom bit of the window */
 
+    if (r == p) {
+        BIGNUM *p_dup = BN_CTX_get(ctx);
+
+        if (p_dup == NULL || BN_copy(p_dup, p) == NULL)
+            goto err;
+        p = p_dup;
+    }
+
     if (!BN_one(r))
         goto err;
 
     for (;;) {
+        int wvalue;             /* The 'value' of the window */
+
         if (BN_is_bit_set(p, wstart) == 0) {
             if (!start)
                 if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
@@ -288,7 +297,6 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 
         /* move the 'window' down further */
         wstart -= wend + 1;
-        wvalue = 0;
         start = 0;
         if (wstart < 0)
             break;
@@ -304,7 +312,7 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
                     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
 {
-    int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+    int i, j, bits, ret = 0, wstart, wend, window;
     int start = 1;
     BIGNUM *d, *r;
     const BIGNUM *aa;
@@ -384,7 +392,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
     start = 1;                  /* This is used to avoid multiplication etc
                                  * when there is only the value '1' in the
                                  * buffer. */
-    wvalue = 0;                 /* The 'value' of the window */
     wstart = bits - 1;          /* The top bit of the window */
     wend = 0;                   /* The bottom bit of the window */
 
@@ -404,6 +411,8 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
     if (!bn_to_mont_fixed_top(r, BN_value_one(), mont, ctx))
         goto err;
     for (;;) {
+        int wvalue;             /* The 'value' of the window */
+
         if (BN_is_bit_set(p, wstart) == 0) {
             if (!start) {
                 if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx))
@@ -446,7 +455,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
 
         /* move the 'window' down further */
         wstart -= wend + 1;
-        wvalue = 0;
         start = 0;
         if (wstart < 0)
             break;
@@ -1303,7 +1311,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
 int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                       const BIGNUM *m, BN_CTX *ctx)
 {
-    int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+    int i, j, bits, ret = 0, wstart, wend, window;
     int start = 1;
     BIGNUM *d;
     /* Table of variables obtained from 'ctx' */
@@ -1317,6 +1325,11 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
         return 0;
     }
 
+    if (r == m) {
+        ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT);
+        return 0;
+    }
+
     bits = BN_num_bits(p);
     if (bits == 0) {
         /* x**0 mod 1, or x**0 mod -1 is still zero. */
@@ -1358,14 +1371,23 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
     start = 1;                  /* This is used to avoid multiplication etc
                                  * when there is only the value '1' in the
                                  * buffer. */
-    wvalue = 0;                 /* The 'value' of the window */
     wstart = bits - 1;          /* The top bit of the window */
     wend = 0;                   /* The bottom bit of the window */
 
+    if (r == p) {
+        BIGNUM *p_dup = BN_CTX_get(ctx);
+
+        if (p_dup == NULL || BN_copy(p_dup, p) == NULL)
+            goto err;
+        p = p_dup;
+    }
+
     if (!BN_one(r))
         goto err;
 
     for (;;) {
+        int wvalue;             /* The 'value' of the window */
+
         if (BN_is_bit_set(p, wstart) == 0) {
             if (!start)
                 if (!BN_mod_mul(r, r, r, m, ctx))
@@ -1407,7 +1429,6 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 
         /* move the 'window' down further */
         wstart -= wend + 1;
-        wvalue = 0;
         start = 0;
         if (wstart < 0)
             break;

+ 1 - 1
libs/openssl/crypto/bn/bn_gcd.c

@@ -522,7 +522,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *in,
     if (ctx == NULL) {
         ctx = new_ctx = BN_CTX_new_ex(NULL);
         if (ctx == NULL) {
-            ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_BN, ERR_R_BN_LIB);
             return NULL;
         }
     }

+ 5 - 15
libs/openssl/crypto/bn/bn_gf2m.c

@@ -474,10 +474,8 @@ int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
     bn_check_top(p);
 
     arr = OPENSSL_malloc(sizeof(*arr) * max);
-    if (arr == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (arr == NULL)
         return 0;
-    }
     ret = BN_GF2m_poly2arr(p, arr, max);
     if (!ret || ret > max) {
         ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH);
@@ -536,10 +534,8 @@ int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
     bn_check_top(p);
 
     arr = OPENSSL_malloc(sizeof(*arr) * max);
-    if (arr == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (arr == NULL)
         return 0;
-    }
     ret = BN_GF2m_poly2arr(p, arr, max);
     if (!ret || ret > max) {
         ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH);
@@ -915,10 +911,8 @@ int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
     bn_check_top(p);
 
     arr = OPENSSL_malloc(sizeof(*arr) * max);
-    if (arr == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (arr == NULL)
         return 0;
-    }
     ret = BN_GF2m_poly2arr(p, arr, max);
     if (!ret || ret > max) {
         ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH);
@@ -979,10 +973,8 @@ int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
     bn_check_top(p);
 
     arr = OPENSSL_malloc(sizeof(*arr) * max);
-    if (arr == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (arr == NULL)
         return 0;
-    }
     ret = BN_GF2m_poly2arr(p, arr, max);
     if (!ret || ret > max) {
         ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH);
@@ -1115,10 +1107,8 @@ int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
     bn_check_top(p);
 
     arr = OPENSSL_malloc(sizeof(*arr) * max);
-    if (arr == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (arr == NULL)
         goto err;
-    }
     ret = BN_GF2m_poly2arr(p, arr, max);
     if (!ret || ret > max) {
         ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH);

+ 3 - 7
libs/openssl/crypto/bn/bn_intern.c

@@ -29,10 +29,8 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
 
     if (BN_is_zero(scalar)) {
         r = OPENSSL_malloc(1);
-        if (r == NULL) {
-            ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+        if (r == NULL)
             goto err;
-        }
         r[0] = 0;
         *ret_len = 1;
         return r;
@@ -62,10 +60,8 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
                                   * (*ret_len will be set to the actual length, i.e. at most
                                   * BN_num_bits(scalar) + 1)
                                   */
-    if (r == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (r == NULL)
         goto err;
-    }
     window_val = scalar->d[0] & mask;
     j = 0;
     while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len,
@@ -188,7 +184,7 @@ void bn_set_static_words(BIGNUM *a, const BN_ULONG *words, int size)
 int bn_set_words(BIGNUM *a, const BN_ULONG *words, int num_words)
 {
     if (bn_wexpand(a, num_words) == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_BN, ERR_R_BN_LIB);
         return 0;
     }
 

+ 180 - 92
libs/openssl/crypto/bn/bn_lib.c

@@ -244,10 +244,8 @@ BIGNUM *BN_new(void)
 {
     BIGNUM *ret;
 
-    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
         return NULL;
-    }
     ret->flags = BN_FLG_MALLOCED;
     bn_check_top(ret);
     return ret;
@@ -279,10 +277,8 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
         a = OPENSSL_secure_zalloc(words * sizeof(*a));
     else
         a = OPENSSL_zalloc(words * sizeof(*a));
-    if (a == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (a == NULL)
         return NULL;
-    }
 
     assert(b->top <= words);
     if (b->top > 0)
@@ -430,42 +426,102 @@ int BN_set_word(BIGNUM *a, BN_ULONG w)
     return 1;
 }
 
-BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+typedef enum {BIG, LITTLE} endianness_t;
+typedef enum {SIGNED, UNSIGNED} signedness_t;
+
+static BIGNUM *bin2bn(const unsigned char *s, int len, BIGNUM *ret,
+                      endianness_t endianness, signedness_t signedness)
 {
-    unsigned int i, m;
+    int inc;
+    const unsigned char *s2;
+    int inc2;
+    int neg = 0, xor = 0, carry = 0;
+    unsigned int i;
     unsigned int n;
-    BN_ULONG l;
     BIGNUM *bn = NULL;
 
+    /* Negative length is not acceptable */
+    if (len < 0)
+        return NULL;
+
     if (ret == NULL)
         ret = bn = BN_new();
     if (ret == NULL)
         return NULL;
     bn_check_top(ret);
-    /* Skip leading zero's. */
-    for ( ; len > 0 && *s == 0; s++, len--)
+
+    /*
+     * If the input has no bits, the number is considered zero.
+     * This makes calls with s==NULL and len==0 safe.
+     */
+    if (len == 0) {
+        BN_clear(ret);
+        return ret;
+    }
+
+    /*
+     * The loop that does the work iterates from least to most
+     * significant BIGNUM chunk, so we adapt parameters to transfer
+     * input bytes accordingly.
+     */
+    if (endianness == LITTLE) {
+        s2 = s + len - 1;
+        inc2 = -1;
+        inc = 1;
+    } else {
+        s2 = s;
+        inc2 = 1;
+        inc = -1;
+        s += len - 1;
+    }
+
+    /* Take note of the signedness of the input bytes*/
+    if (signedness == SIGNED) {
+        neg = !!(*s2 & 0x80);
+        xor = neg ? 0xff : 0x00;
+        carry = neg;
+    }
+
+    /*
+     * Skip leading sign extensions (the value of |xor|).
+     * This is the only spot where |s2| and |inc2| are used.
+     */
+    for ( ; len > 0 && *s2 == xor; s2 += inc2, len--)
         continue;
-    n = len;
-    if (n == 0) {
+
+    /*
+     * If there was a set of 0xff, we backtrack one byte unless the next
+     * one has a sign bit, as the last 0xff is then part of the actual
+     * number, rather then a mere sign extension.
+     */
+    if (xor == 0xff) {
+        if (len == 0 || !(*s2 & 0x80))
+            len++;
+    }
+    /* If it was all zeros, we're done */
+    if (len == 0) {
         ret->top = 0;
         return ret;
     }
-    i = ((n - 1) / BN_BYTES) + 1;
-    m = ((n - 1) % (BN_BYTES));
-    if (bn_wexpand(ret, (int)i) == NULL) {
+    n = ((len - 1) / BN_BYTES) + 1; /* Number of resulting bignum chunks */
+    if (bn_wexpand(ret, (int)n) == NULL) {
         BN_free(bn);
         return NULL;
     }
-    ret->top = i;
-    ret->neg = 0;
-    l = 0;
-    while (n--) {
-        l = (l << 8L) | *(s++);
-        if (m-- == 0) {
-            ret->d[--i] = l;
-            l = 0;
-            m = BN_BYTES - 1;
+    ret->top = n;
+    ret->neg = neg;
+    for (i = 0; n-- > 0; i++) {
+        BN_ULONG l = 0;        /* Accumulator */
+        unsigned int m = 0;    /* Offset in a bignum chunk, in bits */
+
+        for (; len > 0 && m < BN_BYTES * 8; len--, s += inc, m += 8) {
+            BN_ULONG byte_xored = *s ^ xor;
+            BN_ULONG byte = (byte_xored + carry) & 0xff;
+
+            carry = byte_xored > byte; /* Implicit 1 or 0 */
+            l |= (byte << m);
         }
+        ret->d[i] = l;
     }
     /*
      * need to call this due to clear byte at top if avoiding having the top
@@ -475,30 +531,58 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
     return ret;
 }
 
-typedef enum {big, little} endianess_t;
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+    return bin2bn(s, len, ret, BIG, UNSIGNED);
+}
+
+BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+    return bin2bn(s, len, ret, BIG, SIGNED);
+}
 
-/* ignore negative */
-static
-int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endianess)
+static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen,
+                     endianness_t endianness, signedness_t signedness)
 {
-    int n;
+    int inc;
+    int n, n8;
+    int xor = 0, carry = 0, ext = 0;
     size_t i, lasti, j, atop, mask;
     BN_ULONG l;
 
     /*
-     * In case |a| is fixed-top, BN_num_bytes can return bogus length,
+     * In case |a| is fixed-top, BN_num_bits can return bogus length,
      * but it's assumed that fixed-top inputs ought to be "nominated"
      * even for padded output, so it works out...
      */
-    n = BN_num_bytes(a);
+    n8 = BN_num_bits(a);
+    n = (n8 + 7) / 8;           /* This is what BN_num_bytes() does */
+
+    /* Take note of the signedness of the bignum */
+    if (signedness == SIGNED) {
+        xor = a->neg ? 0xff : 0x00;
+        carry = a->neg;
+
+        /*
+         * if |n * 8 == n|, then the MSbit is set, otherwise unset.
+         * We must compensate with one extra byte if that doesn't
+         * correspond to the signedness of the bignum with regards
+         * to 2's complement.
+         */
+        ext = (n * 8 == n8)
+            ? !a->neg            /* MSbit set on nonnegative bignum */
+            : a->neg;            /* MSbit unset on negative bignum */
+    }
+
     if (tolen == -1) {
-        tolen = n;
-    } else if (tolen < n) {     /* uncommon/unlike case */
+        tolen = n + ext;
+    } else if (tolen < n + ext) { /* uncommon/unlike case */
         BIGNUM temp = *a;
 
         bn_correct_top(&temp);
-        n = BN_num_bytes(&temp);
-        if (tolen < n)
+        n8 = BN_num_bits(&temp);
+        n = (n8 + 7) / 8;       /* This is what BN_num_bytes() does */
+        if (tolen < n + ext)
             return -1;
     }
 
@@ -510,19 +594,30 @@ int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endiane
         return tolen;
     }
 
+    /*
+     * The loop that does the work iterates from least significant
+     * to most significant BIGNUM limb, so we adapt parameters to
+     * transfer output bytes accordingly.
+     */
+    if (endianness == LITTLE) {
+        inc = 1;
+    } else {
+        inc = -1;
+        to += tolen - 1;         /* Move to the last byte, not beyond */
+    }
+
     lasti = atop - 1;
     atop = a->top * BN_BYTES;
-    if (endianess == big)
-        to += tolen; /* start from the end of the buffer */
     for (i = 0, j = 0; j < (size_t)tolen; j++) {
-        unsigned char val;
+        unsigned char byte, byte_xored;
+
         l = a->d[i / BN_BYTES];
         mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
-        val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
-        if (endianess == big)
-            *--to = val;
-        else
-            *to++ = val;
+        byte = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
+        byte_xored = byte ^ xor;
+        *to = (unsigned char)(byte_xored + carry);
+        carry = byte_xored > *to; /* Implicit 1 or 0 */
+        to += inc;
         i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
     }
 
@@ -533,66 +628,43 @@ int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
 {
     if (tolen < 0)
         return -1;
-    return bn2binpad(a, to, tolen, big);
+    return bn2binpad(a, to, tolen, BIG, UNSIGNED);
+}
+
+int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen)
+{
+    if (tolen < 0)
+        return -1;
+    return bn2binpad(a, to, tolen, BIG, SIGNED);
 }
 
 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
 {
-    return bn2binpad(a, to, -1, big);
+    return bn2binpad(a, to, -1, BIG, UNSIGNED);
 }
 
 BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
 {
-    unsigned int i, m;
-    unsigned int n;
-    BN_ULONG l;
-    BIGNUM *bn = NULL;
+    return bin2bn(s, len, ret, LITTLE, UNSIGNED);
+}
 
-    if (ret == NULL)
-        ret = bn = BN_new();
-    if (ret == NULL)
-        return NULL;
-    bn_check_top(ret);
-    s += len;
-    /* Skip trailing zeroes. */
-    for ( ; len > 0 && s[-1] == 0; s--, len--)
-        continue;
-    n = len;
-    if (n == 0) {
-        ret->top = 0;
-        return ret;
-    }
-    i = ((n - 1) / BN_BYTES) + 1;
-    m = ((n - 1) % (BN_BYTES));
-    if (bn_wexpand(ret, (int)i) == NULL) {
-        BN_free(bn);
-        return NULL;
-    }
-    ret->top = i;
-    ret->neg = 0;
-    l = 0;
-    while (n--) {
-        s--;
-        l = (l << 8L) | *s;
-        if (m-- == 0) {
-            ret->d[--i] = l;
-            l = 0;
-            m = BN_BYTES - 1;
-        }
-    }
-    /*
-     * need to call this due to clear byte at top if avoiding having the top
-     * bit set (-ve number)
-     */
-    bn_correct_top(ret);
-    return ret;
+BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+    return bin2bn(s, len, ret, LITTLE, SIGNED);
 }
 
 int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
 {
     if (tolen < 0)
         return -1;
-    return bn2binpad(a, to, tolen, little);
+    return bn2binpad(a, to, tolen, LITTLE, UNSIGNED);
+}
+
+int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen)
+{
+    if (tolen < 0)
+        return -1;
+    return bn2binpad(a, to, tolen, LITTLE, SIGNED);
 }
 
 BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret)
@@ -604,6 +676,15 @@ BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret)
     return BN_bin2bn(s, len, ret);
 }
 
+BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+    DECLARE_IS_ENDIAN;
+
+    if (IS_LITTLE_ENDIAN)
+        return BN_signed_lebin2bn(s, len, ret);
+    return BN_signed_bin2bn(s, len, ret);
+}
+
 int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen)
 {
     DECLARE_IS_ENDIAN;
@@ -613,6 +694,15 @@ int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen)
     return BN_bn2binpad(a, to, tolen);
 }
 
+int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen)
+{
+    DECLARE_IS_ENDIAN;
+
+    if (IS_LITTLE_ENDIAN)
+        return BN_signed_bn2lebin(a, to, tolen);
+    return BN_signed_bn2bin(a, to, tolen);
+}
+
 int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
 {
     int i;
@@ -963,10 +1053,8 @@ BN_GENCB *BN_GENCB_new(void)
 {
     BN_GENCB *ret;
 
-    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
         return NULL;
-    }
 
     return ret;
 }

+ 5 - 2
libs/openssl/crypto/bn/bn_local.h

@@ -243,8 +243,11 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
                       int num);
 
 struct bignum_st {
-    BN_ULONG *d;                /* Pointer to an array of 'BN_BITS2' bit
-                                 * chunks. */
+    BN_ULONG *d;                /*
+                                 * Pointer to an array of 'BN_BITS2' bit
+                                 * chunks. These chunks are organised in
+                                 * a least significant chunk first order.
+                                 */
     int top;                    /* Index of last used d +1. */
     /* The next are internal book keeping for bn_expand. */
     int dmax;                   /* Size of the d array. */

+ 12 - 4
libs/openssl/crypto/bn/bn_mod.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2023 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,11 @@ int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
      * always holds)
      */
 
+    if (r == d) {
+        ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT);
+        return 0;
+    }
+
     if (!(BN_mod(r, m, d, ctx)))
         return 0;
     if (!r->neg)
@@ -58,10 +63,8 @@ int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
 
     if (mtop > sizeof(storage) / sizeof(storage[0])) {
         tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG));
-        if (tp == NULL) {
-            ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+        if (tp == NULL)
             return 0;
-        }
     }
 
     ap = a->d != NULL ? a->d : tp;
@@ -186,6 +189,11 @@ int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
 int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                      const BIGNUM *m)
 {
+    if (r == m) {
+        ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT);
+        return 0;
+    }
+
     if (!BN_sub(r, a, b))
         return 0;
     if (r->neg)

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

@@ -229,10 +229,8 @@ BN_MONT_CTX *BN_MONT_CTX_new(void)
 {
     BN_MONT_CTX *ret;
 
-    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
         return NULL;
-    }
 
     BN_MONT_CTX_init(ret);
     ret->flags = BN_FLG_MALLOCED;

+ 1 - 1
libs/openssl/crypto/bn/bn_mul.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 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

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

@@ -251,7 +251,7 @@ const BIGNUM *BN_get0_nist_prime_521(void)
 
 /*
  * To avoid more recent compilers (specifically clang-14) from treating this
- * code as a violation of the strict aliasing conditions and omiting it, this
+ * code as a violation of the strict aliasing conditions and omitting it, this
  * cannot be declared as a function.  Moreover, the dst parameter cannot be
  * cached in a local since this no longer references the union and again falls
  * foul of the strict aliasing criteria.  Refer to #18225 for the initial

+ 2 - 4
libs/openssl/crypto/bn/bn_prime.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 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
@@ -145,10 +145,8 @@ int BN_generate_prime_ex2(BIGNUM *ret, int bits, int safe,
     }
 
     mods = OPENSSL_zalloc(sizeof(*mods) * NUMPRIMES);
-    if (mods == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (mods == NULL)
         return 0;
-    }
 
     BN_CTX_start(ctx);
     t = BN_CTX_get(ctx);

+ 1 - 3
libs/openssl/crypto/bn/bn_rand.c

@@ -41,10 +41,8 @@ static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom,
     mask = 0xff << (bit + 1);
 
     buf = OPENSSL_malloc(bytes);
-    if (buf == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if (buf == NULL)
         goto err;
-    }
 
     /* make a random number and set the top and bottom bits */
     b = flag == NORMAL ? RAND_bytes_ex(libctx, buf, bytes, strength)

+ 1 - 3
libs/openssl/crypto/bn/bn_recp.c

@@ -21,10 +21,8 @@ BN_RECP_CTX *BN_RECP_CTX_new(void)
 {
     BN_RECP_CTX *ret;
 
-    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
         return NULL;
-    }
 
     bn_init(&(ret->N));
     bn_init(&(ret->Nr));

+ 1 - 1
libs/openssl/crypto/bn/bn_rsa_fips186_4.c

@@ -143,7 +143,7 @@ static int bn_rsa_fips186_4_find_aux_prob_prime(const BIGNUM *Xp1,
     BN_set_flags(p1, BN_FLG_CONSTTIME);
 
     /* Find the first odd number >= Xp1 that is probably prime */
-    for(;;) {
+    for (;;) {
         i++;
         BN_GENCB_call(cb, 0, i);
         /* MR test with trial division */

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 2013-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2013-2021 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

+ 3 - 7
libs/openssl/crypto/buffer/buffer.c

@@ -33,10 +33,8 @@ BUF_MEM *BUF_MEM_new(void)
     BUF_MEM *ret;
 
     ret = OPENSSL_zalloc(sizeof(*ret));
-    if (ret == NULL) {
-        ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
+    if (ret == NULL)
         return NULL;
-    }
     return ret;
 }
 
@@ -87,7 +85,7 @@ size_t BUF_MEM_grow(BUF_MEM *str, size_t len)
     }
     /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
     if (len > LIMIT_BEFORE_EXPANSION) {
-        ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_BUF, ERR_R_PASSED_INVALID_ARGUMENT);
         return 0;
     }
     n = (len + 3) / 3 * 4;
@@ -96,7 +94,6 @@ size_t BUF_MEM_grow(BUF_MEM *str, size_t len)
     else
         ret = OPENSSL_realloc(str->data, n);
     if (ret == NULL) {
-        ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
         len = 0;
     } else {
         str->data = ret;
@@ -125,7 +122,7 @@ size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
     }
     /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
     if (len > LIMIT_BEFORE_EXPANSION) {
-        ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_BUF, ERR_R_PASSED_INVALID_ARGUMENT);
         return 0;
     }
     n = (len + 3) / 3 * 4;
@@ -134,7 +131,6 @@ size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
     else
         ret = OPENSSL_clear_realloc(str->data, str->max, n);
     if (ret == NULL) {
-        ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE);
         len = 0;
     } else {
         str->data = ret;

+ 1 - 46
libs/openssl/crypto/cast/cast_local.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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,51 +11,6 @@
 # include <stdlib.h>
 #endif
 
-#undef c2l
-#define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
-                         l|=((unsigned long)(*((c)++)))<< 8L, \
-                         l|=((unsigned long)(*((c)++)))<<16L, \
-                         l|=((unsigned long)(*((c)++)))<<24L)
-
-/* NOTE - c is not incremented as per c2l */
-#undef c2ln
-#define c2ln(c,l1,l2,n) { \
-                        c+=n; \
-                        l1=l2=0; \
-                        switch (n) { \
-                        case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
-                        case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
-                        case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
-                        case 5: l2|=((unsigned long)(*(--(c))));     \
-                        case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
-                        case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
-                        case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
-                        case 1: l1|=((unsigned long)(*(--(c))));     \
-                                } \
-                        }
-
-#undef l2c
-#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
-                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
-
-/* NOTE - c is not incremented as per l2c */
-#undef l2cn
-#define l2cn(l1,l2,c,n) { \
-                        c+=n; \
-                        switch (n) { \
-                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
-                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
-                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
-                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
-                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
-                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
-                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
-                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
-                                } \
-                        }
-
 /* NOTE - c is not incremented as per n2l */
 #define n2ln(c,l1,l2,n) { \
                         c+=n; \

+ 1 - 1
libs/openssl/crypto/chacha/chacha_enc.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2020 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

+ 34 - 9
libs/openssl/crypto/cmac/cmac.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2010-2023 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/cmac.h>
 #include <openssl/err.h>
 
+#define LOCAL_BUF_SIZE 2048
 struct CMAC_CTX_st {
     /* Cipher context to use */
     EVP_CIPHER_CTX *cctx;
@@ -53,10 +54,8 @@ CMAC_CTX *CMAC_CTX_new(void)
 {
     CMAC_CTX *ctx;
 
-    if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) {
-        ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
+    if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL)
         return NULL;
-    }
     ctx->cctx = EVP_CIPHER_CTX_new();
     if (ctx->cctx == NULL) {
         OPENSSL_free(ctx);
@@ -164,6 +163,8 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
 {
     const unsigned char *data = in;
     int bl;
+    size_t max_burst_blocks, cipher_blocks;
+    unsigned char buf[LOCAL_BUF_SIZE];
 
     if (ctx->nlast_block == -1)
         return 0;
@@ -190,11 +191,35 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
             return 0;
     }
     /* Encrypt all but one of the complete blocks left */
-    while (dlen > (size_t)bl) {
-        if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0)
-            return 0;
-        dlen -= bl;
-        data += bl;
+
+    max_burst_blocks = LOCAL_BUF_SIZE / bl;
+    cipher_blocks = (dlen - 1) / bl;
+    if (max_burst_blocks == 0) {
+        /*
+         * When block length is greater than local buffer size,
+         * use ctx->tbl as cipher output.
+         */
+        while (dlen > (size_t)bl) {
+            if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0)
+                return 0;
+            dlen -= bl;
+            data += bl;
+        }
+    } else {
+        while (cipher_blocks > max_burst_blocks) {
+            if (EVP_Cipher(ctx->cctx, buf, data, max_burst_blocks * bl) <= 0)
+                return 0;
+            dlen -= max_burst_blocks * bl;
+            data += max_burst_blocks * bl;
+            cipher_blocks -= max_burst_blocks;
+        }
+        if (cipher_blocks > 0) {
+            if (EVP_Cipher(ctx->cctx, buf, data, cipher_blocks * bl) <= 0)
+                return 0;
+            dlen -= cipher_blocks * bl;
+            data += cipher_blocks * bl;
+            memcpy(ctx->tbl, &buf[(cipher_blocks - 1) * bl], bl);
+        }
     }
     /* Copy any data left to last block buffer */
     memcpy(ctx->last_block, data, dlen);

+ 5 - 0
libs/openssl/crypto/cmp/cmp_err.c

@@ -84,8 +84,12 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     "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_GETTING_GENP), "getting genp"},
     {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_OPTION), "invalid option"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ROOTCAKEYUPDATE),
+     "invalid rootcakeyupdate"},
     {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"},
@@ -139,6 +143,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSACTIONID_UNMATCHED),
     "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_PKIBODY), "unexpected pkibody"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS),
     "unexpected pkistatus"},

+ 37 - 6
libs/openssl/crypto/cmp/cmp_local.h

@@ -25,7 +25,7 @@
 # include <openssl/x509v3.h>
 # include "crypto/x509.h"
 
-#define IS_NULL_DN(name) (X509_NAME_get_entry(name, 0) == NULL)
+# define IS_NULL_DN(name) (X509_NAME_get_entry(name, 0) == NULL)
 
 /*
  * this structure is used to store the context for CMP sessions
@@ -49,10 +49,13 @@ struct ossl_cmp_ctx_st {
     int keep_alive; /* persistent connection: 0=no, 1=prefer, 2=require */
     int msg_timeout; /* max seconds to wait for each CMP message round trip */
     int total_timeout; /* max number of seconds an enrollment may take, incl. */
+    int tls_used; /* whether to use TLS for client-side HTTP connections */
     /* attempts polling for a response if a 'waiting' PKIStatus is received */
     time_t end_time; /* session start time + totaltimeout */
+# ifndef OPENSSL_NO_HTTP
     OSSL_HTTP_bio_cb_t http_cb;
     void *http_cb_arg; /* allows to store optional argument to cb */
+# endif
 
     /* server authentication */
     /*
@@ -101,7 +104,8 @@ struct ossl_cmp_ctx_st {
     /* certificate template */
     EVP_PKEY *newPkey; /* explicit new private/public key for cert enrollment */
     int newPkey_priv; /* flag indicating if newPkey contains private key */
-    X509_NAME *issuer; /* issuer name to used in cert template */
+    X509_NAME *issuer; /* issuer name to used in cert template, also in rr */
+    ASN1_INTEGER *serialNumber; /* certificate serial number to use in rr */
     int days; /* Number of days new certificates are asked to be valid for */
     X509_NAME *subjectName; /* subject name to be used in cert template */
     STACK_OF(GENERAL_NAME) *subjectAltNames; /* to add to the cert template */
@@ -118,7 +122,7 @@ struct ossl_cmp_ctx_st {
     int revocationReason; /* revocation reason code to be included in RR */
     STACK_OF(OSSL_CMP_ITAV) *genm_ITAVs; /* content of general message */
 
-    /* result returned in responses */
+    /* result returned in responses, so far supporting only one certResponse */
     int status; /* PKIStatus of last received IP/CP/KUP/RP/error or -1 */
     OSSL_CMP_PKIFREETEXT *statusString; /* of last IP/CP/KUP/RP/error */
     int failInfoCode; /* failInfoCode of last received IP/CP/KUP/error, or -1 */
@@ -202,6 +206,9 @@ typedef struct ossl_cmp_cakeyupdanncontent_st {
 } OSSL_CMP_CAKEYUPDANNCONTENT;
 DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT)
 
+typedef struct ossl_cmp_rootcakeyupdate_st OSSL_CMP_ROOTCAKEYUPDATE;
+DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE)
+
 /*-
  * declared already here as it will be used in OSSL_CMP_MSG (nested) and
  * infoType and infoValue
@@ -247,6 +254,12 @@ struct ossl_cmp_itav_st {
         OSSL_CMP_MSGS *origPKIMessage;
         /* NID_id_it_suppLangTags - Supported Language Tags */
         STACK_OF(ASN1_UTF8STRING) *suppLangTagsValue;
+        /* NID_id_it_caCerts - CA Certificates */
+        STACK_OF(X509) *caCerts;
+        /* NID_id_it_rootCaCert - Root CA Certificate */
+        X509 *rootCaCert;
+        /* NID_id_it_rootCaKeyUpdate - Root CA Certificate Update */
+        OSSL_CMP_ROOTCAKEYUPDATE *rootCaKeyUpdate;
         /* this is to be used for so far undeclared objects */
         ASN1_TYPE *other;
     } infoValue;
@@ -369,13 +382,15 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ERRORMSGCONTENT)
  *      -- as is used to create and verify the certificate signature
  *      certReqId   INTEGER,
  *      -- to match this confirmation with the corresponding req/rep
- *      statusInfo  PKIStatusInfo OPTIONAL
+ *      statusInfo  PKIStatusInfo OPTIONAL,
+ *      hashAlg [0] AlgorithmIdentifier OPTIONAL
  *   }
  */
 struct ossl_cmp_certstatus_st {
     ASN1_OCTET_STRING *certHash;
     ASN1_INTEGER *certReqId;
     OSSL_CMP_PKISI *statusInfo;
+    X509_ALGOR *hashAlg; /* 0 */
 } /* OSSL_CMP_CERTSTATUS */;
 DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTSTATUS)
 typedef STACK_OF(OSSL_CMP_CERTSTATUS) OSSL_CMP_CERTCONFIRMCONTENT;
@@ -446,7 +461,7 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_POLLREPCONTENT)
 
 /*-
  * PKIHeader ::= SEQUENCE {
- *     pvno                INTEGER     { cmp1999(1), cmp2000(2) },
+ *     pvno                INTEGER     { cmp1999(1), cmp2000(2), cmp2021(3) },
  *     sender              GeneralName,
  *     -- identifies the sender
  *     recipient           GeneralName,
@@ -708,6 +723,7 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PROTECTEDPART)
  *   }       -- or HMAC [RFC2104, RFC2202])
  */
 /*-
+ *   Not supported:
  *   id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30}
  *   DHBMParameter ::= SEQUENCE {
  *           owf                 AlgorithmIdentifier,
@@ -730,6 +746,21 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PROTECTEDPART)
  *   }
  */
 
+/*
+ * RootCaKeyUpdateContent ::= SEQUENCE {
+ *      newWithNew       CMPCertificate,
+ *      newWithOld   [0] CMPCertificate OPTIONAL,
+ *      oldWithNew   [1] CMPCertificate OPTIONAL
+ * }
+ */
+
+struct ossl_cmp_rootcakeyupdate_st {
+    X509 *newWithNew;
+    X509 *newWithOld;
+    X509 *oldWithNew;
+} /* OSSL_CMP_ROOTCAKEYUPDATE */;
+DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE)
+
 /* from cmp_asn.c */
 int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a);
 
@@ -777,7 +808,7 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
 # define ossl_cmp_info(ctx, msg)  ossl_cmp_log(INFO,  ctx, msg)
 # define ossl_cmp_debug(ctx, msg) ossl_cmp_log(DEBUG, ctx, msg)
 # define ossl_cmp_trace(ctx, msg) ossl_cmp_log(TRACE, ctx, msg)
-int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert);
+int ossl_cmp_ctx_set1_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert);
 int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status);
 int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx,
                                    OSSL_CMP_PKIFREETEXT *text);

+ 4 - 4
libs/openssl/crypto/cmp/cmp_util.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Nokia 2007-2019
  * Copyright Siemens AG 2015-2019
  *
@@ -53,8 +53,7 @@ static OSSL_CMP_severity parse_level(const char *level)
     if (end_level == NULL)
         return -1;
 
-    if (strncmp(level, OSSL_CMP_LOG_PREFIX,
-                strlen(OSSL_CMP_LOG_PREFIX)) == 0)
+    if (HAS_PREFIX(level, OSSL_CMP_LOG_PREFIX))
         level += strlen(OSSL_CMP_LOG_PREFIX);
     len = end_level - level;
     if (len > max_level_len)
@@ -190,7 +189,7 @@ void OSSL_CMP_print_errors_cb(OSSL_CMP_log_cb_t log_fn)
                 BIO_free(bio);
             }
 #else
-            /* ERR_raise(ERR_LIB_CMP, CMP_R_NO_STDIO) makes no sense during error printing */
+            /* ERR_raise(..., CMP_R_NO_STDIO) would make no sense here */
 #endif
         } else {
             if (log_fn(component, file, line, OSSL_CMP_LOG_ERR, msg) <= 0)
@@ -244,6 +243,7 @@ int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
                                     const ASN1_OCTET_STRING *src)
 {
     ASN1_OCTET_STRING *new;
+
     if (tgt == NULL) {
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return 0;

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2020 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
@@ -83,6 +83,7 @@ ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
         ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
         ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
 } ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_SignedData)
 
 ASN1_SEQUENCE(CMS_OriginatorInfo) = {
         ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0),

+ 1 - 1
libs/openssl/crypto/cms/cms_dd.c

@@ -66,7 +66,7 @@ int ossl_cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain,
     CMS_DigestedData *dd;
 
     if (mctx == NULL) {
-        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
         goto err;
     }
 

+ 5 - 9
libs/openssl/crypto/cms/cms_enc.c

@@ -45,7 +45,7 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec,
 
     b = BIO_new(BIO_f_cipher());
     if (b == NULL) {
-        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_CMS, ERR_R_BIO_LIB);
         return NULL;
     }
 
@@ -121,10 +121,8 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec,
     /* Generate random session key */
     if (!enc || !ec->key) {
         tkey = OPENSSL_malloc(tkeylen);
-        if (tkey == NULL) {
-            ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+        if (tkey == NULL)
             goto err;
-        }
         if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
             goto err;
     }
@@ -168,7 +166,7 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec,
     if (enc) {
         calg->parameter = ASN1_TYPE_new();
         if (calg->parameter == NULL) {
-            ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
             goto err;
         }
         if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) {
@@ -211,10 +209,8 @@ int ossl_cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
 {
     ec->cipher = cipher;
     if (key) {
-        if ((ec->key = OPENSSL_malloc(keylen)) == NULL) {
-            ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+        if ((ec->key = OPENSSL_malloc(keylen)) == NULL)
             return 0;
-        }
         memcpy(ec->key, key, keylen);
     }
     ec->keylen = keylen;
@@ -235,7 +231,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
     if (ciph) {
         cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
         if (!cms->d.encryptedData) {
-            ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
             return 0;
         }
         cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);

+ 88 - 57
libs/openssl/crypto/cms/cms_env.c

@@ -83,7 +83,7 @@ static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
     if (cms->d.other == NULL) {
         cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
         if (cms->d.envelopedData == NULL) {
-            ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
             return NULL;
         }
         cms->d.envelopedData->version = 0;
@@ -102,7 +102,7 @@ cms_auth_enveloped_data_init(CMS_ContentInfo *cms)
     if (cms->d.other == NULL) {
         cms->d.authEnvelopedData = M_ASN1_new_of(CMS_AuthEnvelopedData);
         if (cms->d.authEnvelopedData == NULL) {
-            ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
             return NULL;
         }
         /* Defined in RFC 5083 - Section 2.1. "AuthEnvelopedData Type" */
@@ -241,18 +241,18 @@ CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher,
 
     cms = CMS_ContentInfo_new_ex(libctx, propq);
     if (cms == NULL)
-        goto merr;
+        goto err;
     env = cms_enveloped_data_init(cms);
     if (env == NULL)
-        goto merr;
+        goto err;
 
     if (!ossl_cms_EncryptedContent_init(env->encryptedContentInfo, cipher, NULL,
                                         0, ossl_cms_get0_cmsctx(cms)))
-        goto merr;
+        goto err;
     return cms;
- merr:
+ err:
     CMS_ContentInfo_free(cms);
-    ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+    ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
     return NULL;
 }
 
@@ -261,6 +261,44 @@ CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
     return CMS_EnvelopedData_create_ex(cipher, NULL, NULL);
 }
 
+BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data,
+                               EVP_PKEY *pkey, X509 *cert,
+                               ASN1_OCTET_STRING *secret, unsigned int flags,
+                               OSSL_LIB_CTX *libctx, const char *propq)
+{
+    CMS_ContentInfo *ci;
+    BIO *bio = NULL;
+    int res = 0;
+
+    if (env == NULL) {
+        ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+
+    if ((ci = CMS_ContentInfo_new_ex(libctx, propq)) == NULL
+            || (bio = BIO_new(BIO_s_mem())) == NULL)
+        goto end;
+    ci->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
+    ci->d.envelopedData = env;
+    if (secret != NULL
+        && CMS_decrypt_set1_password(ci, (unsigned char *)
+                                     ASN1_STRING_get0_data(secret),
+                                     ASN1_STRING_length(secret)) != 1)
+        goto end;
+    res = CMS_decrypt(ci, secret == NULL ? pkey : NULL,
+                      secret == NULL ? cert : NULL, detached_data, bio, flags);
+
+ end:
+    if (ci != NULL)
+        ci->d.envelopedData = NULL; /* do not indirectly free |env| */
+    CMS_ContentInfo_free(ci);
+    if (!res) {
+        BIO_free(bio);
+        bio = NULL;
+    }
+    return bio;
+}
+
 CMS_ContentInfo *
 CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx,
                                 const char *propq)
@@ -281,7 +319,7 @@ CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx,
     return cms;
  merr:
     CMS_ContentInfo_free(cms);
-    ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+    ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
     return NULL;
 }
 
@@ -364,8 +402,10 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
 
     /* Initialize recipient info */
     ri = M_ASN1_new_of(CMS_RecipientInfo);
-    if (ri == NULL)
-        goto merr;
+    if (ri == NULL) {
+        ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     pk = X509_get0_pubkey(recip);
     if (pk == NULL) {
@@ -392,13 +432,13 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
 
     }
 
-    if (!sk_CMS_RecipientInfo_push(ris, ri))
-        goto merr;
+    if (!sk_CMS_RecipientInfo_push(ris, ri)) {
+        ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB);
+        goto err;
+    }
 
     return ri;
 
- merr:
-    ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
  err:
     M_ASN1_free_of(ri, CMS_RecipientInfo);
     return NULL;
@@ -509,11 +549,8 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
         goto err;
 
     ek = OPENSSL_malloc(eklen);
-
-    if (ek == NULL) {
-        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+    if (ek == NULL)
         goto err;
-    }
 
     if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
         goto err;
@@ -590,25 +627,17 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
     if (!ossl_cms_env_asn1_ctrl(ri, 1))
         goto err;
 
-    if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
-                         ktri->encryptedKey->data,
-                         ktri->encryptedKey->length) <= 0)
-        goto err;
+    if (EVP_PKEY_is_a(pkey, "RSA"))
+        /* upper layer CMS code incorrectly assumes that a successful RSA
+         * decryption means that the key matches ciphertext (which never
+         * was the case, implicit rejection or not), so to make it work
+         * disable implicit rejection for RSA keys */
+        EVP_PKEY_CTX_ctrl_str(ktri->pctx, "rsa_pkcs1_implicit_rejection", "0");
 
-    ek = OPENSSL_malloc(eklen);
-    if (ek == NULL) {
-        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+    if (evp_pkey_decrypt_alloc(ktri->pctx, &ek, &eklen, fixlen,
+                               ktri->encryptedKey->data,
+                               ktri->encryptedKey->length) <= 0)
         goto err;
-    }
-
-    if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
-                         ktri->encryptedKey->data,
-                         ktri->encryptedKey->length) <= 0
-            || eklen == 0
-            || (fixlen != 0 && eklen != fixlen)) {
-        ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB);
-        goto err;
-    }
 
     ret = 1;
 
@@ -714,24 +743,32 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
 
     /* Initialize recipient info */
     ri = M_ASN1_new_of(CMS_RecipientInfo);
-    if (!ri)
-        goto merr;
+    if (!ri) {
+        ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
+        goto err;
+    }
 
     ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
-    if (!ri->d.kekri)
-        goto merr;
+    if (!ri->d.kekri) {
+        ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
+        goto err;
+    }
     ri->type = CMS_RECIPINFO_KEK;
 
     kekri = ri->d.kekri;
 
     if (otherTypeId) {
         kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
-        if (kekri->kekid->other == NULL)
-            goto merr;
+        if (kekri->kekid->other == NULL) {
+            ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
+            goto err;
+        }
     }
 
-    if (!sk_CMS_RecipientInfo_push(ris, ri))
-        goto merr;
+    if (!sk_CMS_RecipientInfo_push(ris, ri)) {
+        ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB);
+        goto err;
+    }
 
     /* After this point no calls can fail */
 
@@ -749,13 +786,11 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
         kekri->kekid->other->keyAttr = otherType;
     }
 
-    X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
-                    OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
+    (void)X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, OBJ_nid2obj(nid),
+                          V_ASN1_UNDEF, NULL); /* cannot fail */
 
     return ri;
 
- merr:
-    ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
  err:
     M_ASN1_free_of(ri, CMS_RecipientInfo);
     return NULL;
@@ -814,7 +849,7 @@ static EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen, const CMS_CTX *ctx)
 {
     const char *alg = NULL;
 
-    switch(keylen) {
+    switch (keylen) {
     case 16:
         alg = "AES-128-WRAP";
         break;
@@ -866,14 +901,12 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
 
     /* 8 byte prefix for AES wrap ciphers */
     wkey = OPENSSL_malloc(ec->keylen + 8);
-    if (wkey == NULL) {
-        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+    if (wkey == NULL)
         goto err;
-    }
 
     ctx = EVP_CIPHER_CTX_new();
     if (ctx == NULL) {
-        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
         goto err;
     }
 
@@ -949,14 +982,12 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
     }
 
     ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
-    if (ukey == NULL) {
-        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+    if (ukey == NULL)
         goto err;
-    }
 
     ctx = EVP_CIPHER_CTX_new();
     if (ctx == NULL) {
-        ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
         goto err;
     }
 
@@ -1254,7 +1285,7 @@ int ossl_cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain)
             env->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null();
 
         if (env->unprotectedAttrs == NULL) {
-            ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB);
             return 0;
         }
 

+ 2 - 0
libs/openssl/crypto/cms/cms_err.c

@@ -109,6 +109,8 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key"},
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request"},
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers"},
+    {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_OPERATION_UNSUPPORTED),
+    "operation unsupported"},
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PEER_KEY_ERROR), "peer key error"},
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
     "private key does not match certificate"},

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