1
0
Эх сурвалжийг харах

OpenSSL 3.3.1

Source commit: 96fe61bb0db2d2509837764686191422b7caa46a
Martin Prikryl 1 жил өмнө
parent
commit
c4c4ebb56d
100 өөрчлөгдсөн 6218 нэмэгдсэн , 721 устгасан
  1. 198 8
      libs/openssl/CHANGES.md
  2. 18 0
      libs/openssl/Configurations/10-main.conf
  3. 7 0
      libs/openssl/Configurations/15-android.conf
  4. 5 5
      libs/openssl/Configurations/15-ios.conf
  5. 14 8
      libs/openssl/Configurations/50-nonstop.conf
  6. 1 1
      libs/openssl/Configurations/descrip.mms.tmpl
  7. 20 2
      libs/openssl/Configurations/platform/AIX.pm
  8. 3 1
      libs/openssl/Configurations/platform/Unix.pm
  9. 61 74
      libs/openssl/Configurations/unix-Makefile.tmpl
  10. 9 0
      libs/openssl/Configurations/windows-makefile.tmpl
  11. 13 1
      libs/openssl/Configure
  12. 12 2
      libs/openssl/INSTALL.md
  13. 132 3
      libs/openssl/NEWS.md
  14. 2 2
      libs/openssl/NOTES-ANDROID.md
  15. 8 7
      libs/openssl/NOTES-NONSTOP.md
  16. 2 2
      libs/openssl/NOTES-WINDOWS.md
  17. 2 2
      libs/openssl/VERSION.dat
  18. 269 93
      libs/openssl/apps/cmp.c
  19. 4 3
      libs/openssl/apps/crl.c
  20. 2 1
      libs/openssl/apps/enc.c
  21. 5 2
      libs/openssl/apps/engine.c
  22. 10 2
      libs/openssl/apps/genpkey.c
  23. 5 1
      libs/openssl/apps/include/opt.h
  24. 1 16
      libs/openssl/apps/lib/apps.c
  25. 101 19
      libs/openssl/apps/lib/cmp_mock_srv.c
  26. 2 8
      libs/openssl/apps/lib/http_server.c
  27. 1 7
      libs/openssl/apps/lib/s_socket.c
  28. 1 7
      libs/openssl/apps/ocsp.c
  29. 86 7
      libs/openssl/apps/rand.c
  30. 2 2
      libs/openssl/apps/rehash.c
  31. 3 2
      libs/openssl/apps/req.c
  32. 30 14
      libs/openssl/apps/s_server.c
  33. 2 3
      libs/openssl/apps/s_time.c
  34. 120 58
      libs/openssl/apps/speed.c
  35. 20 6
      libs/openssl/apps/x509.c
  36. 25 0
      libs/openssl/build.info
  37. 0 3
      libs/openssl/crypto/aes/aes_x86core.c
  38. 710 0
      libs/openssl/crypto/aes/asm/aes-riscv64-zvbb-zvkg-zvkned.pl
  39. 376 0
      libs/openssl/crypto/aes/asm/aes-riscv64-zvkb-zvkned.pl
  40. 1376 0
      libs/openssl/crypto/aes/asm/aes-riscv64-zvkned.pl
  41. 1 1
      libs/openssl/crypto/aes/asm/aesp8-ppc.pl
  42. 765 3
      libs/openssl/crypto/aes/asm/aesv8-armx.pl
  43. 4 1
      libs/openssl/crypto/aes/build.info
  44. 5 1
      libs/openssl/crypto/arm_arch.h
  45. 8 2
      libs/openssl/crypto/armcap.c
  46. 3 5
      libs/openssl/crypto/asn1/a_time.c
  47. 5 1
      libs/openssl/crypto/asn1/asn1_err.c
  48. 9 1
      libs/openssl/crypto/asn1/tasn_dec.c
  49. 3 2
      libs/openssl/crypto/bio/bio_dump.c
  50. 1 1
      libs/openssl/crypto/bio/bio_lib.c
  51. 3 1
      libs/openssl/crypto/bio/bio_meth.c
  52. 0 3
      libs/openssl/crypto/bio/bio_sock.c
  53. 1 1
      libs/openssl/crypto/bio/bss_dgram.c
  54. 1 1
      libs/openssl/crypto/bn/bn_gcd.c
  55. 1 1
      libs/openssl/crypto/bn/bn_mod.c
  56. 476 0
      libs/openssl/crypto/chacha/asm/chacha-riscv64-zbb-zvkb.pl
  57. 6 0
      libs/openssl/crypto/chacha/build.info
  58. 7 3
      libs/openssl/crypto/chacha/chacha_enc.c
  59. 56 0
      libs/openssl/crypto/chacha/chacha_riscv.c
  60. 9 5
      libs/openssl/crypto/cmac/cmac.c
  61. 36 18
      libs/openssl/crypto/cmp/cmp_asn.c
  62. 162 34
      libs/openssl/crypto/cmp/cmp_client.c
  63. 13 1
      libs/openssl/crypto/cmp/cmp_ctx.c
  64. 8 1
      libs/openssl/crypto/cmp/cmp_err.c
  65. 10 0
      libs/openssl/crypto/cmp/cmp_hdr.c
  66. 10 1
      libs/openssl/crypto/cmp/cmp_local.h
  67. 41 5
      libs/openssl/crypto/cmp/cmp_msg.c
  68. 165 63
      libs/openssl/crypto/cmp/cmp_server.c
  69. 89 60
      libs/openssl/crypto/cmp/cmp_vfy.c
  70. 1 1
      libs/openssl/crypto/cms/cms_enc.c
  71. 9 1
      libs/openssl/crypto/cms/cms_pwri.c
  72. 1 1
      libs/openssl/crypto/conf/conf_lib.c
  73. 92 47
      libs/openssl/crypto/conf/conf_mod.c
  74. 1 1
      libs/openssl/crypto/conf/conf_sap.c
  75. 2 2
      libs/openssl/crypto/dh/dh_check.c
  76. 1 1
      libs/openssl/crypto/dsa/dsa_check.c
  77. 2 2
      libs/openssl/crypto/dso/dso_dl.c
  78. 2 2
      libs/openssl/crypto/dso/dso_dlfcn.c
  79. 1 1
      libs/openssl/crypto/ec/curve448/ed448.h
  80. 13 0
      libs/openssl/crypto/err/err_mark.c
  81. 15 0
      libs/openssl/crypto/err/openssl.txt
  82. 5 1
      libs/openssl/crypto/evp/bio_enc.c
  83. 35 2
      libs/openssl/crypto/evp/digest.c
  84. 13 13
      libs/openssl/crypto/evp/evp_enc.c
  85. 1 1
      libs/openssl/crypto/evp/evp_fetch.c
  86. 2 2
      libs/openssl/crypto/evp/evp_key.c
  87. 27 9
      libs/openssl/crypto/evp/evp_lib.c
  88. 3 1
      libs/openssl/crypto/evp/evp_local.h
  89. 30 1
      libs/openssl/crypto/evp/keymgmt_meth.c
  90. 3 2
      libs/openssl/crypto/evp/legacy_sha.c
  91. 1 19
      libs/openssl/crypto/evp/pmeth_lib.c
  92. 24 1
      libs/openssl/crypto/http/http_client.c
  93. 12 5
      libs/openssl/crypto/http/http_err.c
  94. 1 1
      libs/openssl/crypto/initthread.c
  95. 1 1
      libs/openssl/crypto/lhash/lh_stats.c
  96. 56 12
      libs/openssl/crypto/lhash/lhash.c
  97. 5 1
      libs/openssl/crypto/lhash/lhash_local.h
  98. 2 2
      libs/openssl/crypto/loongarch64cpuid.pl
  99. 297 0
      libs/openssl/crypto/md5/asm/md5-loongarch64.pl
  100. 4 0
      libs/openssl/crypto/md5/build.info

+ 198 - 8
libs/openssl/CHANGES.md

@@ -12,6 +12,7 @@ appropriate release branch.
 OpenSSL Releases
 OpenSSL Releases
 ----------------
 ----------------
 
 
+ - [OpenSSL 3.3](#openssl-33)
  - [OpenSSL 3.2](#openssl-32)
  - [OpenSSL 3.2](#openssl-32)
  - [OpenSSL 3.1](#openssl-31)
  - [OpenSSL 3.1](#openssl-31)
  - [OpenSSL 3.0](#openssl-30)
  - [OpenSSL 3.0](#openssl-30)
@@ -22,10 +23,10 @@ OpenSSL Releases
  - [OpenSSL 1.0.0](#openssl-100)
  - [OpenSSL 1.0.0](#openssl-100)
  - [OpenSSL 0.9.x](#openssl-09x)
  - [OpenSSL 0.9.x](#openssl-09x)
 
 
-OpenSSL 3.2
+OpenSSL 3.3
 -----------
 -----------
 
 
-### Changes between 3.2.1 and 3.2.2 [4 Jun 2024]
+### Changes between 3.3.0 and 3.3.1 [4 Jun 2024]
 
 
  * Fixed potential use after free after SSL_free_buffers() is called.
  * Fixed potential use after free after SSL_free_buffers() is called.
 
 
@@ -67,6 +68,201 @@ OpenSSL 3.2
 
 
    *Tomáš Mráz*
    *Tomáš Mráz*
 
 
+### Changes between 3.2 and 3.3.0 [9 Apr 2024]
+
+ * The `-verify` option to the `openssl crl` and `openssl req` will make
+   the program exit with 1 on failure.
+
+   *Vladimír Kotal*
+
+ * The BIO_get_new_index() function can only be called 127 times before it
+   reaches its upper bound of BIO_TYPE_MASK. It will now correctly return an
+   error of -1 once it is exhausted. Users may need to reserve using this
+   function for cases where BIO_find_type() is required. Either BIO_TYPE_NONE
+   or BIO_get_new_index() can be used to supply a type to BIO_meth_new().
+
+   *Shane Lontis*
+
+ * Added API functions SSL_SESSION_get_time_ex(), SSL_SESSION_set_time_ex()
+   using time_t which is Y2038 safe on 32 bit systems when 64 bit time
+   is enabled (e.g via setting glibc macro _TIME_BITS=64).
+
+   *Ijtaba Hussain*
+
+ * The d2i_ASN1_GENERALIZEDTIME(), d2i_ASN1_UTCTIME(), ASN1_TIME_check(), and
+   related functions have been augmented to check for a minimum length of
+   the input string, in accordance with ITU-T X.690 section 11.7 and 11.8.
+
+   *Job Snijders*
+
+ * Unknown entries in TLS SignatureAlgorithms, ClientSignatureAlgorithms
+   config options and the respective calls to SSL[_CTX]_set1_sigalgs() and
+   SSL[_CTX]_set1_client_sigalgs() that start with `?` character are
+   ignored and the configuration will still be used.
+
+   Similarly unknown entries that start with `?` character in a TLS
+   Groups config option or set with SSL[_CTX]_set1_groups_list() are ignored
+   and the configuration will still be used.
+
+   In both cases if the resulting list is empty, an error is returned.
+
+   *Tomáš Mráz*
+
+ * The EVP_PKEY_fromdata function has been augmented to allow for the derivation
+   of CRT (Chinese Remainder Theorem) parameters when requested.  See the
+   OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ param in the EVP_PKEY-RSA documentation.
+
+   *Neil Horman*
+
+ * The activate and soft_load configuration settings for providers in
+   openssl.cnf have been updated to require a value of [1|yes|true|on]
+   (in lower or UPPER case) to enable the setting. Conversely a value
+   of [0|no|false|off] will disable the setting. All other values, or the
+   omission of a value for these settings will result in an error.
+
+    *Neil Horman*
+
+ * Added `-set_issuer` and `-set_subject` options to `openssl x509` to
+   override the Issuer and Subject when creating a certificate. The `-subj`
+   option now is an alias for `-set_subject`.
+
+    *Job Snijders, George Michaelson*
+
+ * OPENSSL_sk_push() and sk_<TYPE>_push() functions now return 0 instead of -1
+   if called with a NULL stack argument.
+
+   *Tomáš Mráz*
+
+ * In `openssl speed`, changed the default hash function used with `hmac` from
+   `md5` to `sha256`.
+
+   *James Muir*
+
+ * Added several new features of CMPv3 defined in RFC 9480 and RFC 9483:
+   - `certProfile` request message header and respective `-profile` CLI option
+   - support for delayed delivery of all types of response messages
+
+   *David von Oheimb*
+
+ * The build of exporters (such as `.pc` files for pkg-config) cleaned up to
+   be less hard coded in the build file templates, and to allow easier
+   addition of more exporters.  With that, an exporter for CMake is also
+   added.
+
+   *Richard Levitte*
+
+ * The BLAKE2s hash algorithm matches BLAKE2b's support
+   for configurable output length.
+
+   *Ahelenia Ziemiańska*
+
+ * New option `SSL_OP_PREFER_NO_DHE_KEX`, which allows configuring a TLS1.3
+   server to prefer session resumption using PSK-only key exchange over PSK
+   with DHE, if both are available.
+
+   *Markus Minichmayr, Tapkey GmbH*
+
+ * New API `SSL_write_ex2`, which can be used to send an end-of-stream (FIN)
+   condition in an optimised way when using QUIC.
+
+   *Hugo Landau*
+
+ * New atexit configuration switch, which controls whether the OPENSSL_cleanup
+   is registered when libcrypto is unloaded. This is turned off on NonStop
+   configurations because of loader differences on that platform compared to
+   Linux.
+
+   *Randall S. Becker*
+
+ * Support for qlog for tracing QUIC connections has been added.
+
+   The qlog output from OpenSSL currently uses a pre-standard draft version of
+   qlog. The output from OpenSSL will change in incompatible ways in future
+   releases, and is not subject to any format stability or compatibility
+   guarantees at this time. This functionality can be
+   disabled with the build-time option `no-unstable-qlog`. See the
+   openssl-qlog(7) manpage for details.
+
+   *Hugo Landau*
+
+ * Added APIs to allow configuring the negotiated idle timeout for QUIC
+   connections, and to allow determining the number of additional streams
+   that can currently be created for a QUIC connection.
+
+   *Hugo Landau*
+
+ * Added APIs to allow disabling implicit QUIC event processing for
+   QUIC SSL objects, allowing applications to control when event handling
+   occurs. Refer to the SSL_get_value_uint(3) manpage for details.
+
+   *Hugo Landau*
+
+ * Limited support for polling of QUIC connection and stream objects in a
+   non-blocking manner. Refer to the SSL_poll(3) manpage for details.
+
+   *Hugo Landau*
+
+ * Added APIs to allow querying the size and utilisation of a QUIC stream's
+   write buffer. Refer to the SSL_get_value_uint(3) manpage for details.
+
+   *Hugo Landau*
+
+ * New limit on HTTP response headers is introduced to HTTP client. The
+   default limit is set to 256 header lines. If limit is exceeded the
+   response processing stops with error HTTP_R_RESPONSE_TOO_MANY_HDRLINES.
+   Application may call OSSL_HTTP_REQ_CTX_set_max_response_hdr_lines(3)
+   to change the default. Setting the value to 0 disables the limit.
+
+   *Alexandr Nedvedicky*
+
+ * Applied AES-GCM unroll8 optimisation to Microsoft Azure Cobalt 100
+
+   *Tom Cosgrove*
+
+ * Added X509_STORE_get1_objects to avoid issues with the existing
+   X509_STORE_get0_objects API in multi-threaded applications. Refer to the
+   documentation for details.
+
+   *David Benjamin*
+
+ * Added assembly implementation for md5 on loongarch64
+
+   *Min Zhou*
+
+ * Optimized AES-CTR for ARM Neoverse V1 and V2
+
+   *Fisher Yu*
+
+ * Enable AES and SHA3 optimisations on Applie Silicon M3-based MacOS systems
+   similar to M1/M2.
+
+   *Tom Cosgrove*
+
+ * Added a new EVP_DigestSqueeze() API. This allows SHAKE to squeeze multiple
+   times with different output sizes.
+
+   *Shane Lontis, Holger Dengler*
+
+ * Various optimizations for cryptographic routines using RISC-V vector crypto
+   extensions
+
+   *Christoph Müllner, Charalampos Mitrodimas, Ard Biesheuvel, Phoebe Chen,
+    Jerry Shih*
+
+ * Accept longer context for TLS 1.2 exporters
+
+   While RFC 5705 implies that the maximum length of a context for exporters is
+   65535 bytes as the length is embedded in uint16, the previous implementation
+   enforced a much smaller limit, which is less than 1024 bytes. This
+   restriction has been removed.
+
+   *Daiki Ueno*
+
+OpenSSL 3.2
+-----------
+
+### Changes between 3.2.1 and 3.2.2 [xx XXX xxxx]
+
  * Fixed an issue where some non-default TLS server configurations can cause
  * Fixed an issue where some non-default TLS server configurations can cause
    unbounded memory growth when processing TLSv1.3 sessions. An attacker may
    unbounded memory growth when processing TLSv1.3 sessions. An attacker may
    exploit certain server configurations to trigger unbounded memory growth that
    exploit certain server configurations to trigger unbounded memory growth that
@@ -85,12 +281,6 @@ OpenSSL 3.2
 
 
    *Matt Caswell*
    *Matt Caswell*
 
 
- * New atexit configuration switch, which controls whether the OPENSSL_cleanup
-   is registered when libcrypto is unloaded. This can be used on platforms
-   where using atexit() from shared libraries causes crashes on exit.
-
-   *Randall S. Becker*
-
  * Fixed bug where SSL_export_keying_material() could not be used with QUIC
  * Fixed bug where SSL_export_keying_material() could not be used with QUIC
    connections. (#23560)
    connections. (#23560)
 
 

+ 18 - 0
libs/openssl/Configurations/10-main.conf

@@ -1414,6 +1414,19 @@ my %targets = (
         AR               => add("-X32"),
         AR               => add("-X32"),
         RANLIB           => add("-X32"),
         RANLIB           => add("-X32"),
     },
     },
+    # shared_target of "aix-solib" builds shared libraries packaged
+    # without archives.  This improves the behavior of inter-library
+    # references (libssl depending on libcrypto) when building with
+    # shlib_variant.
+    # You'll get:  libxxx.so (import library, used when linking applications)
+    #              libxxx.so.ver (shared object)
+    #              libxxx.a (static library archive)
+    # and for runtime, you only need libxxx.so.ver.  libxxx.so and libxxx.a
+    # can be installed along with include files to make an SDK
+    "aix-cc-solib" => {
+        inherit_from     => [ "aix-cc" ],
+        shared_target    => "aix-solib",
+    },
     "aix64-cc" => {
     "aix64-cc" => {
         inherit_from     => [ "aix-common" ],
         inherit_from     => [ "aix-common" ],
         CC               => "cc",
         CC               => "cc",
@@ -1432,6 +1445,10 @@ my %targets = (
         AR               => add("-X64"),
         AR               => add("-X64"),
         RANLIB           => add("-X64"),
         RANLIB           => add("-X64"),
     },
     },
+    "aix64-cc-solib" => {
+        inherit_from     => [ "aix64-cc" ],
+        shared_target    => "aix-solib",
+    },
 
 
 # SIEMENS BS2000/OSD: an EBCDIC-based mainframe
 # SIEMENS BS2000/OSD: an EBCDIC-based mainframe
     "BS2000-OSD" => {
     "BS2000-OSD" => {
@@ -2045,6 +2062,7 @@ my %targets = (
         cflag_incfirst   => '/FIRST_INCLUDE=',
         cflag_incfirst   => '/FIRST_INCLUDE=',
         lib_defines      =>
         lib_defines      =>
             add("OPENSSL_USE_NODELETE",
             add("OPENSSL_USE_NODELETE",
+                "_XOPEN_SOURCE", "_XOPEN_SOURCE_EXTENDED=1",
                 sub {
                 sub {
                     return vms_info()->{def_zlib}
                     return vms_info()->{def_zlib}
                         ? "LIBZ=\"\"\"".vms_info()->{def_zlib}."\"\"\"" : ();
                         ? "LIBZ=\"\"\"".vms_info()->{def_zlib}."\"\"\"" : ();

+ 7 - 0
libs/openssl/Configurations/15-android.conf

@@ -12,6 +12,7 @@
         arm64  => "aarch64-linux-android",
         arm64  => "aarch64-linux-android",
         mips   => "mipsel-linux-android",
         mips   => "mipsel-linux-android",
         mips64 => "mips64el-linux-android",
         mips64 => "mips64el-linux-android",
+        riscv64 => "riscv64-linux-android",
         x86    => "i686-linux-android",
         x86    => "i686-linux-android",
         x86_64 => "x86_64-linux-android",
         x86_64 => "x86_64-linux-android",
     );
     );
@@ -270,6 +271,12 @@ my %targets = (
         perlasm_scheme   => "elf",
         perlasm_scheme   => "elf",
     },
     },
 
 
+    "android-riscv64" => {
+        inherit_from     => [ "android" ],
+        asm_arch         => 'riscv64',
+        perlasm_scheme   => "linux64",
+    },
+
     ####################################################################
     ####################################################################
     # Backward compatible targets, (might) require $CROSS_SYSROOT
     # Backward compatible targets, (might) require $CROSS_SYSROOT
     #
     #

+ 5 - 5
libs/openssl/Configurations/15-ios.conf

@@ -19,14 +19,14 @@ my %targets = (
         # thus targeting iPhone pre-3GS, but it's assumed to be irrelevant
         # thus targeting iPhone pre-3GS, but it's assumed to be irrelevant
         # at this point.
         # at this point.
         CC               => "xcrun -sdk iphoneos cc",
         CC               => "xcrun -sdk iphoneos cc",
-        cflags           => add("-arch armv7 -mios-version-min=6.0.0 -fno-common"),
+        cflags           => add("-arch armv7 -fno-common"),
         asm_arch         => 'armv4',
         asm_arch         => 'armv4',
         perlasm_scheme   => "ios32",
         perlasm_scheme   => "ios32",
     },
     },
     "ios64-xcrun" => {
     "ios64-xcrun" => {
         inherit_from     => [ "ios-common" ],
         inherit_from     => [ "ios-common" ],
         CC               => "xcrun -sdk iphoneos cc",
         CC               => "xcrun -sdk iphoneos cc",
-        cflags           => add("-arch arm64 -mios-version-min=7.0.0 -fno-common"),
+        cflags           => add("-arch arm64 -fno-common"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
         bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
         asm_arch         => 'aarch64',
         asm_arch         => 'aarch64',
         perlasm_scheme   => "ios64",
         perlasm_scheme   => "ios64",
@@ -38,7 +38,7 @@ my %targets = (
     "iossimulator-arm64-xcrun" => {
     "iossimulator-arm64-xcrun" => {
         inherit_from     => [ "ios-common" ],
         inherit_from     => [ "ios-common" ],
         CC               => "xcrun -sdk iphonesimulator cc",
         CC               => "xcrun -sdk iphonesimulator cc",
-        cflags           => add("-arch arm64 -mios-simulator-version-min=7.0.0 -fno-common"),
+        cflags           => add("-arch arm64 -fno-common"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         asm_arch         => 'aarch64',
         asm_arch         => 'aarch64',
         perlasm_scheme   => "ios64",
         perlasm_scheme   => "ios64",
@@ -46,7 +46,7 @@ my %targets = (
     "iossimulator-i386-xcrun" => {
     "iossimulator-i386-xcrun" => {
         inherit_from     => [ "ios-common" ],
         inherit_from     => [ "ios-common" ],
         CC               => "xcrun -sdk iphonesimulator cc",
         CC               => "xcrun -sdk iphonesimulator cc",
-        cflags           => add("-arch i386 -mios-simulator-version-min=7.0.0 -fno-common"),
+        cflags           => add("-arch i386 -fno-common"),
         bn_ops           => "BN_LLONG",
         bn_ops           => "BN_LLONG",
         asm_arch         => 'x86',
         asm_arch         => 'x86',
         perlasm_scheme   => "macosx",
         perlasm_scheme   => "macosx",
@@ -54,7 +54,7 @@ my %targets = (
     "iossimulator-x86_64-xcrun" => {
     "iossimulator-x86_64-xcrun" => {
         inherit_from     => [ "ios-common" ],
         inherit_from     => [ "ios-common" ],
         CC               => "xcrun -sdk iphonesimulator cc",
         CC               => "xcrun -sdk iphonesimulator cc",
-        cflags           => add("-arch x86_64 -mios-simulator-version-min=7.0.0 -fno-common"),
+        cflags           => add("-arch x86_64 -fno-common"),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         asm_arch         => 'x86_64',
         asm_arch         => 'x86_64',
         perlasm_scheme   => "macosx",
         perlasm_scheme   => "macosx",

+ 14 - 8
libs/openssl/Configurations/50-nonstop.conf

@@ -21,6 +21,8 @@
         shared_extension => ".so",
         shared_extension => ".so",
         ex_libs          => add('-lrld'),
         ex_libs          => add('-lrld'),
         enable           => ['egd'],
         enable           => ['egd'],
+	# Not currently inherited
+        disable          => ['atexit'],
         dso_scheme       => 'DLFCN',
         dso_scheme       => 'DLFCN',
         sys_id           => 'TANDEM',
         sys_id           => 'TANDEM',
     },
     },
@@ -178,7 +180,7 @@
                               'nonstop-archenv-x86_64-oss',
                               'nonstop-archenv-x86_64-oss',
                               'nonstop-ilp32',
                               'nonstop-ilp32',
                               'nonstop-efloat-x86_64' ],
                               'nonstop-efloat-x86_64' ],
-        disable          => ['threads'],
+        disable          => ['threads','atexit'],
     },
     },
     'nonstop-nsx_put' => {
     'nonstop-nsx_put' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
@@ -188,6 +190,7 @@
                               'nonstop-model-put' ],
                               'nonstop-model-put' ],
         multilib         => '-put',
         multilib         => '-put',
         multibin         => '-put',
         multibin         => '-put',
+        disable          => ['atexit'],
     },
     },
     'nonstop-nsx_64' => {
     'nonstop-nsx_64' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
@@ -196,7 +199,7 @@
                               'nonstop-efloat-x86_64' ],
                               'nonstop-efloat-x86_64' ],
         multilib         => '64',
         multilib         => '64',
         multibin         => '64',
         multibin         => '64',
-        disable          => ['threads'],
+        disable          => ['threads','atexit'],
     },
     },
     'nonstop-nsx_64_put' => {
     'nonstop-nsx_64_put' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
@@ -206,18 +209,19 @@
                               'nonstop-model-put' ],
                               'nonstop-model-put' ],
         multilib         => '64-put',
         multilib         => '64-put',
         multibin         => '64-put',
         multibin         => '64-put',
+        disable          => ['atexit'],
     },
     },
     'nonstop-nsx_g' => {
     'nonstop-nsx_g' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
                               'nonstop-archenv-x86_64-guardian',
                               'nonstop-archenv-x86_64-guardian',
                               'nonstop-ilp32', 'nonstop-nfloat-x86_64' ],
                               'nonstop-ilp32', 'nonstop-nfloat-x86_64' ],
-        disable          => ['threads'],
+        disable          => ['threads','atexit'],
     },
     },
     'nonstop-nsx_g_tandem' => {
     'nonstop-nsx_g_tandem' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
                               'nonstop-archenv-x86_64-guardian',
                               'nonstop-archenv-x86_64-guardian',
                               'nonstop-ilp32', 'nonstop-tfloat-x86_64' ],
                               'nonstop-ilp32', 'nonstop-tfloat-x86_64' ],
-        disable          => ['threads'],
+        disable          => ['threads','atexit'],
     },
     },
     'nonstop-nsv' => {
     'nonstop-nsv' => {
         inherit_from     => [ 'nonstop-nsx' ],
         inherit_from     => [ 'nonstop-nsx' ],
@@ -227,7 +231,7 @@
                               'nonstop-archenv-itanium-oss',
                               'nonstop-archenv-itanium-oss',
                               'nonstop-ilp32',
                               'nonstop-ilp32',
                               'nonstop-efloat-itanium' ],
                               'nonstop-efloat-itanium' ],
-        disable          => ['threads'],
+        disable          => ['threads','atexit'],
     },
     },
     'nonstop-nse_put' => {
     'nonstop-nse_put' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
@@ -237,6 +241,7 @@
                               'nonstop-model-put' ],
                               'nonstop-model-put' ],
         multilib         => '-put',
         multilib         => '-put',
         multibin         => '-put',
         multibin         => '-put',
+        disable          => ['atexit'],
     },
     },
     'nonstop-nse_64' => {
     'nonstop-nse_64' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
@@ -245,7 +250,7 @@
                               'nonstop-efloat-itanium' ],
                               'nonstop-efloat-itanium' ],
         multilib         => '64',
         multilib         => '64',
         multibin         => '64',
         multibin         => '64',
-        disable          => ['threads'],
+        disable          => ['threads','atexit'],
     },
     },
     'nonstop-nse_64_put' => {
     'nonstop-nse_64_put' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
@@ -255,17 +260,18 @@
                               'nonstop-model-put' ],
                               'nonstop-model-put' ],
         multilib         => '64-put',
         multilib         => '64-put',
         multibin         => '64-put',
         multibin         => '64-put',
+        disable          => ['atexit'],
     },
     },
     'nonstop-nse_g' => {
     'nonstop-nse_g' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
                               'nonstop-archenv-itanium-guardian',
                               'nonstop-archenv-itanium-guardian',
                               'nonstop-ilp32', 'nonstop-nfloat-itanium' ],
                               'nonstop-ilp32', 'nonstop-nfloat-itanium' ],
-        disable          => ['threads'],
+        disable          => ['threads','atexit'],
     },
     },
 
 
     'nonstop-nse_g_tandem' => {
     'nonstop-nse_g_tandem' => {
         inherit_from     => [ 'nonstop-common',
         inherit_from     => [ 'nonstop-common',
                               'nonstop-archenv-itanium-guardian',
                               'nonstop-archenv-itanium-guardian',
                               'nonstop-ilp32', 'nonstop-tfloat-itanium' ],
                               'nonstop-ilp32', 'nonstop-tfloat-itanium' ],
-        disable          => ['threads'],
+        disable          => ['threads','atexit'],
     },
     },

+ 1 - 1
libs/openssl/Configurations/descrip.mms.tmpl

@@ -239,7 +239,7 @@
       # from these directories.
       # from these directories.
       push @{$unified_info{includes_extra}->{$obj}}, qw(./quic);
       push @{$unified_info{includes_extra}->{$obj}}, qw(./quic);
   }
   }
-  foreach (grep /\[\.ssl\.(?:quic|record|statem)\].*?\.o$/, keys %{$unified_info{sources}}) {
+  foreach (grep /\[\.ssl\.(?:quic|record|statem|rio)\].*?\.o$/, keys %{$unified_info{sources}}) {
       my $obj = platform->obj($_);
       my $obj = platform->obj($_);
       # Most of the files in [.ssl.record] and [.ssl.statem] include
       # Most of the files in [.ssl.record] and [.ssl.statem] include
       # "../ssl_local.h", which includes things like "record/record.h".
       # "../ssl_local.h", which includes things like "record/record.h".

+ 20 - 2
libs/openssl/Configurations/platform/AIX.pm

@@ -13,12 +13,16 @@ require platform::Unix;
 use configdata;
 use configdata;
 
 
 sub dsoext              { '.so' }
 sub dsoext              { '.so' }
-sub shlibextsimple      { '.a' }
+sub shlibextsimple      { return '.so' if $target{shared_target} eq "aix-solib";
+			  '.a'}
 
 
 # In shared mode, the default static library names clashes with the final
 # In shared mode, the default static library names clashes with the final
 # "simple" full shared library name, so we add '_a' to the basename of the
 # "simple" full shared library name, so we add '_a' to the basename of the
-# static libraries in that case.
+# static libraries in that case, unless in solib mode (using only .so
+# files for shared libraries, and not packaging them inside archives)
 sub staticname {
 sub staticname {
+    return platform::Unix->staticname($_[1]) if $target{shared_target} eq "aix-solib";
+
     # Non-installed libraries are *always* static, and their names remain
     # Non-installed libraries are *always* static, and their names remain
     # the same, except for the mandatory extension
     # the same, except for the mandatory extension
     my $in_libname = platform::BASE->staticname($_[1]);
     my $in_libname = platform::BASE->staticname($_[1]);
@@ -27,3 +31,17 @@ sub staticname {
 
 
     return platform::BASE->staticname($_[1]) . ($disabled{shared} ? '' : '_a');
     return platform::BASE->staticname($_[1]) . ($disabled{shared} ? '' : '_a');
 }
 }
+
+# In solib mode, we do not install the simple symlink (we install the import
+# library).  In regular mode, we install the symlink.
+sub sharedlib_simple {
+    return undef if $target{shared_target} eq "aix-solib";
+    return platform::Unix->sharedlib_simple($_[1], $_[0]->shlibextsimple());
+}
+
+# In solib mode, we install the import library.  In regular mode, we have
+# no import library.
+sub sharedlib_import {
+    return platform::Unix->sharedlib_simple($_[1]) if $target{shared_target} eq "aix-solib";
+    return undef;
+}

+ 3 - 1
libs/openssl/Configurations/platform/Unix.pm

@@ -73,7 +73,9 @@ sub sharedlib_simple {
     my $name = $_[0]->sharedname($_[1]);
     my $name = $_[0]->sharedname($_[1]);
     my $simplename = $_[0]->sharedname_simple($_[1]);
     my $simplename = $_[0]->sharedname_simple($_[1]);
     my $ext = $_[0]->shlibext();
     my $ext = $_[0]->shlibext();
-    my $simpleext = $_[0]->shlibextsimple();
+    # Allow override of the extension passed in as parameter
+    my $simpleext = $_[2];
+    $simpleext = $_[0]->shlibextsimple() unless defined $simpleext;
 
 
     return undef unless defined $simplename && defined $name;
     return undef unless defined $simplename && defined $name;
     return undef if ($name eq $simplename && $ext eq $simpleext);
     return undef if ($name eq $simplename && $ext eq $simpleext);

+ 61 - 74
libs/openssl/Configurations/unix-Makefile.tmpl

@@ -11,8 +11,13 @@
      sub windowsdll { $config{target} =~ /^(?:Cygwin|mingw)/ }
      sub windowsdll { $config{target} =~ /^(?:Cygwin|mingw)/ }
 
 
      # Shared AIX support is special. We put libcrypto[64].so.ver into
      # Shared AIX support is special. We put libcrypto[64].so.ver into
-     # libcrypto.a and use libcrypto_a.a as static one.
-     sub sharedaix  { !$disabled{shared} && $config{target} =~ /^aix/ }
+     # libcrypto.a and use libcrypto_a.a as static one, unless using
+     # shared_target style aix-solib.  In that mode, create
+     # libcrypto.so as a link-import library that inserts runtime
+     # dependencies on libcrypto.so.ver, and the static library is
+     # named libcrypto.a.
+     sub sharedaix  { !$disabled{shared} && $target{shared_target} =~ /^aix(?!-solib$)/ }
+     sub sharedaix_solib  { !$disabled{shared} && $target{shared_target} =~ /^aix-solib$/ }
 
 
      our $sover_dirname = platform->shlib_version_as_filename();
      our $sover_dirname = platform->shlib_version_as_filename();
 
 
@@ -199,6 +204,18 @@ INSTALL_PROGRAMS={-
                         grep { !$unified_info{attributes}->{programs}->{$_}->{noinst} }
                         grep { !$unified_info{attributes}->{programs}->{$_}->{noinst} }
                         @{$unified_info{programs}}))
                         @{$unified_info{programs}}))
 -}
 -}
+INSTALL_EXPORTERS_PKGCONFIG={-
+        join(" \\\n" . ' ' x 28,
+             fill_lines(" ", $COLUMNS - 28,
+                        grep { $unified_info{attributes}->{generate}->{$_}->{exporter} eq 'pkg-config'}
+                        sort keys %{$unified_info{generate}}))
+-}
+INSTALL_EXPORTERS_CMAKE={-
+        join(" \\\n" . ' ' x 24,
+             fill_lines(" ", $COLUMNS - 24,
+                        grep { $unified_info{attributes}->{generate}->{$_}->{exporter} eq 'cmake'}
+                        sort keys %{$unified_info{generate}}))
+-}
 BIN_SCRIPTS={-
 BIN_SCRIPTS={-
         join(" \\\n" . ' ' x 12,
         join(" \\\n" . ' ' x 12,
              fill_lines(" ", $COLUMNS - 12,
              fill_lines(" ", $COLUMNS - 12,
@@ -320,6 +337,9 @@ BINDIR={- our $bindir = $config{bindir};
 bindir={- file_name_is_absolute($bindir)
 bindir={- file_name_is_absolute($bindir)
           ? $bindir : '$(INSTALLTOP)/$(BINDIR)' -}
           ? $bindir : '$(INSTALLTOP)/$(BINDIR)' -}
 
 
+PKGCONFIGDIR=$(libdir)/pkgconfig
+CMAKECONFIGDIR=$(libdir)/cmake/OpenSSL
+
 MANDIR=$(INSTALLTOP)/share/man
 MANDIR=$(INSTALLTOP)/share/man
 DOCDIR=$(INSTALLTOP)/share/doc/$(BASENAME)
 DOCDIR=$(INSTALLTOP)/share/doc/$(BASENAME)
 HTMLDIR=$(DOCDIR)/html
 HTMLDIR=$(DOCDIR)/html
@@ -521,7 +541,7 @@ build_man_docs: $(MANDOCS1) $(MANDOCS3) $(MANDOCS5) $(MANDOCS7) ## Create manpag
 build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7) ## Create HTML documentation
 build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7) ## Create HTML documentation
 
 
 build_generated: $(GENERATED_MANDATORY)
 build_generated: $(GENERATED_MANDATORY)
-build_libs_nodep: libcrypto.pc libssl.pc openssl.pc
+build_libs_nodep: $(LIBS) {- join(" ",map { platform->sharedlib_simple($_) // platform->sharedlib_import($_) // platform->sharedlib($_) // () } @{$unified_info{libraries}}) -}
 build_modules_nodep: $(MODULES)
 build_modules_nodep: $(MODULES)
 build_programs_nodep: $(PROGRAMS) $(SCRIPTS)
 build_programs_nodep: $(PROGRAMS) $(SCRIPTS)
 
 
@@ -607,7 +627,6 @@ clean: libclean ## Clean the workspace, keep the configuration
 	$(RM) tags TAGS doc-nits md-nits
 	$(RM) tags TAGS doc-nits md-nits
 	$(RM) -r test/test-runs
 	$(RM) -r test/test-runs
 	$(RM) providers/fips*.new
 	$(RM) providers/fips*.new
-	$(RM) openssl.pc libcrypto.pc libssl.pc
 	-find . -type l \! -name '.*' -exec $(RM) {} \;
 	-find . -type l \! -name '.*' -exec $(RM) {} \;
 
 
 distclean: clean ## Clean and remove the configuration
 distclean: clean ## Clean and remove the configuration
@@ -746,12 +765,12 @@ install_dev: install_runtime_libs
 		fn1=`basename "$$s1"`; \
 		fn1=`basename "$$s1"`; \
 		fn2=`basename "$$s2"`; \
 		fn2=`basename "$$s2"`; \
 		fn3=`basename "$$s3"`; \
 		fn3=`basename "$$s3"`; \
-		: {- output_off(); output_on() unless windowsdll() or sharedaix(); "" -}; \
+		: {- output_off(); output_on() unless windowsdll() or sharedaix() or sharedaix_solib(); "" -}; \
 		if [ "$$fn2" != "" ]; then \
 		if [ "$$fn2" != "" ]; then \
 			$(ECHO) "link $(DESTDIR)$(libdir)/$$fn2 -> $(DESTDIR)$(libdir)/$$fn1"; \
 			$(ECHO) "link $(DESTDIR)$(libdir)/$$fn2 -> $(DESTDIR)$(libdir)/$$fn1"; \
 			ln -sf $$fn1 "$(DESTDIR)$(libdir)/$$fn2"; \
 			ln -sf $$fn1 "$(DESTDIR)$(libdir)/$$fn2"; \
 		fi; \
 		fi; \
-		: {- output_off() unless windowsdll() or sharedaix(); output_on() if windowsdll(); "" -}; \
+		: {- output_off() unless windowsdll() or sharedaix() or sharedaix_solib(); output_on() if windowsdll() or sharedaix_solib(); "" -}; \
 		if [ "$$fn3" != "" ]; then \
 		if [ "$$fn3" != "" ]; then \
 			$(ECHO) "install $$s3 -> $(DESTDIR)$(libdir)/$$fn3"; \
 			$(ECHO) "install $$s3 -> $(DESTDIR)$(libdir)/$$fn3"; \
 			cp $$s3 "$(DESTDIR)$(libdir)/$$fn3.new"; \
 			cp $$s3 "$(DESTDIR)$(libdir)/$$fn3.new"; \
@@ -759,7 +778,7 @@ install_dev: install_runtime_libs
 			mv -f "$(DESTDIR)$(libdir)/$$fn3.new" \
 			mv -f "$(DESTDIR)$(libdir)/$$fn3.new" \
 			      "$(DESTDIR)$(libdir)/$$fn3"; \
 			      "$(DESTDIR)$(libdir)/$$fn3"; \
 		fi; \
 		fi; \
-		: {- output_off() if windowsdll(); output_on() if sharedaix(); "" -}; \
+		: {- output_off() if windowsdll() or sharedaix_solib(); output_on() if sharedaix(); "" -}; \
 		a="$(DESTDIR)$(libdir)/$$fn2"; \
 		a="$(DESTDIR)$(libdir)/$$fn2"; \
 		$(ECHO) "install $$s1 -> $$a"; \
 		$(ECHO) "install $$s1 -> $$a"; \
 		if [ -f $$a ]; then ( trap "rm -rf /tmp/ar.$$$$" INT 0; \
 		if [ -f $$a ]; then ( trap "rm -rf /tmp/ar.$$$$" INT 0; \
@@ -777,16 +796,20 @@ install_dev: install_runtime_libs
 		: {- output_off() if sharedaix(); output_on(); "" -}; \
 		: {- output_off() if sharedaix(); output_on(); "" -}; \
 	done
 	done
 	@ : {- output_on() if $disabled{shared}; "" -}
 	@ : {- output_on() if $disabled{shared}; "" -}
-	@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(libdir)/pkgconfig"
-	@$(ECHO) "install libcrypto.pc -> $(DESTDIR)$(libdir)/pkgconfig/libcrypto.pc"
-	@cp libcrypto.pc "$(DESTDIR)$(libdir)/pkgconfig"
-	@chmod 644 "$(DESTDIR)$(libdir)/pkgconfig/libcrypto.pc"
-	@$(ECHO) "install libssl.pc -> $(DESTDIR)$(libdir)/pkgconfig/libssl.pc"
-	@cp libssl.pc "$(DESTDIR)$(libdir)/pkgconfig"
-	@chmod 644 "$(DESTDIR)$(libdir)/pkgconfig/libssl.pc"
-	@$(ECHO) "install openssl.pc -> $(DESTDIR)$(libdir)/pkgconfig/openssl.pc"
-	@cp openssl.pc "$(DESTDIR)$(libdir)/pkgconfig"
-	@chmod 644 "$(DESTDIR)$(libdir)/pkgconfig/openssl.pc"
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(PKGCONFIGDIR)"
+	@for e in $(INSTALL_EXPORTERS_PKGCONFIG); do \
+		fn=`basename $$e`; \
+		$(ECHO) "install $$e -> $(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
+		cp $$e "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
+		chmod 644 "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
+	done
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(CMAKECONFIGDIR)
+	@for e in $(INSTALL_EXPORTERS_CMAKE); do \
+		fn=`basename $$e`; \
+		$(ECHO) "install $$e -> $(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \
+		cp $$e $(DESTDIR)$(CMAKECONFIGDIR)/$$fn; \
+		chmod 644 $(DESTDIR)$(CMAKECONFIGDIR)/$$fn; \
+	done
 
 
 uninstall_dev: uninstall_runtime_libs
 uninstall_dev: uninstall_runtime_libs
 	@$(ECHO) "*** Uninstalling development files"
 	@$(ECHO) "*** Uninstalling development files"
@@ -830,10 +853,16 @@ uninstall_dev: uninstall_runtime_libs
 		: {- output_on() unless windowsdll(); "" -}; \
 		: {- output_on() unless windowsdll(); "" -}; \
 	done
 	done
 	@ : {- output_on() if $disabled{shared}; "" -}
 	@ : {- output_on() if $disabled{shared}; "" -}
-	$(RM) "$(DESTDIR)$(libdir)/pkgconfig/libcrypto.pc"
-	$(RM) "$(DESTDIR)$(libdir)/pkgconfig/libssl.pc"
-	$(RM) "$(DESTDIR)$(libdir)/pkgconfig/openssl.pc"
-	-$(RMDIR) "$(DESTDIR)$(libdir)/pkgconfig"
+	@for e in $(INSTALL_EXPORTERS_PKGCONFIG); do \
+		fn=`basename "$$e"`; \
+		$(RM) "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
+	done
+	@for e in $(INSTALL_EXPORTERS_CMAKE); do \
+		fn=`basename "$$e"`; \
+		$(RM) "$(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \
+	done
+	-$(RMDIR) "$(DESTDIR)$(PKGCONFIGDIR)"
+	-$(RMDIR) "$(DESTDIR)$(CMAKECONFIGDIR)"
 	-$(RMDIR) "$(DESTDIR)$(libdir)"
 	-$(RMDIR) "$(DESTDIR)$(libdir)"
 
 
 _install_modules_deps: install_runtime_libs build_modules
 _install_modules_deps: install_runtime_libs build_modules
@@ -1434,59 +1463,6 @@ FORCE:
 
 
 # Building targets ###################################################
 # Building targets ###################################################
 
 
-libcrypto.pc libssl.pc openssl.pc: Makefile $(LIBS) {- join(" ",map { platform->sharedlib_simple($_) // platform->sharedlib_import($_) // platform->sharedlib($_) // () } @{$unified_info{libraries}}) -}
-
-libcrypto.pc:
-	@ ( echo 'prefix=$(INSTALLTOP)'; \
-	    echo 'exec_prefix=$${prefix}'; \
-	    if [ -n "$(LIBDIR)" ]; then \
-	        echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
-	    else \
-	        echo 'libdir=$(libdir)'; \
-	    fi; \
-	    echo 'includedir=$${prefix}/include'; \
-	    echo 'enginesdir=$${libdir}/engines-{- $sover_dirname -}'; \
-	    echo 'modulesdir=$${libdir}/ossl-modules'; \
-	    echo ''; \
-	    echo 'Name: OpenSSL-libcrypto'; \
-	    echo 'Description: OpenSSL cryptography library'; \
-	    echo 'Version: '$(VERSION); \
-	    echo 'Libs: -L$${libdir} -lcrypto'; \
-	    echo 'Libs.private: $(LIB_EX_LIBS)'; \
-	    echo 'Cflags: -I$${includedir}' ) > libcrypto.pc
-
-libssl.pc:
-	@ ( echo 'prefix=$(INSTALLTOP)'; \
-	    echo 'exec_prefix=$${prefix}'; \
-	    if [ -n "$(LIBDIR)" ]; then \
-	        echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
-	    else \
-	        echo 'libdir=$(libdir)'; \
-	    fi; \
-	    echo 'includedir=$${prefix}/include'; \
-	    echo ''; \
-	    echo 'Name: OpenSSL-libssl'; \
-	    echo 'Description: Secure Sockets Layer and cryptography libraries'; \
-	    echo 'Version: '$(VERSION); \
-	    echo 'Requires.private: libcrypto'; \
-	    echo 'Libs: -L$${libdir} -lssl'; \
-	    echo 'Cflags: -I$${includedir}' ) > libssl.pc
-
-openssl.pc:
-	@ ( echo 'prefix=$(INSTALLTOP)'; \
-	    echo 'exec_prefix=$${prefix}'; \
-	    if [ -n "$(LIBDIR)" ]; then \
-	        echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
-	    else \
-	        echo 'libdir=$(libdir)'; \
-	    fi; \
-	    echo 'includedir=$${prefix}/include'; \
-	    echo ''; \
-	    echo 'Name: OpenSSL'; \
-	    echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
-	    echo 'Version: '$(VERSION); \
-	    echo 'Requires: libssl libcrypto' ) > openssl.pc
-
 Makefile: configdata.pm \
 Makefile: configdata.pm \
           {- join(" \\\n" . ' ' x 10,
           {- join(" \\\n" . ' ' x 10,
                   fill_lines(" ", $COLUMNS - 10,
                   fill_lines(" ", $COLUMNS - 10,
@@ -1819,6 +1795,8 @@ EOF
       # libraries for DLLs are a thing.  On platforms that have this mechanism,
       # libraries for DLLs are a thing.  On platforms that have this mechanism,
       # $import has the name of this import library.  On platforms that don't
       # $import has the name of this import library.  On platforms that don't
       # have this mechanism, $import will be |undef|.
       # have this mechanism, $import will be |undef|.
+      # It's also used on AIX in solib mode, which creates import libraries
+      # for the shared libraries.
       my $import = platform->sharedlib_import($args{lib});
       my $import = platform->sharedlib_import($args{lib});
       # $simple is for platforms where full shared library names include the
       # $simple is for platforms where full shared library names include the
       # shared library version, and there's a simpler name that doesn't include
       # shared library version, and there's a simpler name that doesn't include
@@ -1879,9 +1857,18 @@ EOF
           }
           }
       }
       }
       if (defined $import) {
       if (defined $import) {
+          if (sharedaix_solib()) {
+              $recipe .= <<"EOF";
+$import: $full $defs[0]
+	rm -f $import && \\
+	echo \\#!$full > $import && \\
+        cat $defs[0] >>$import
+EOF
+          } else {
       $recipe .= <<"EOF";
       $recipe .= <<"EOF";
 $import: $full
 $import: $full
 EOF
 EOF
+          }
       }
       }
       $recipe .= <<"EOF";
       $recipe .= <<"EOF";
 $full: $fulldeps
 $full: $fulldeps

+ 9 - 0
libs/openssl/Configurations/windows-makefile.tmpl

@@ -155,6 +155,11 @@ MISC_SCRIPTS={-
                          && $unified_info{attributes}->{scripts}->{$_}->{misc} }
                          && $unified_info{attributes}->{scripts}->{$_}->{misc} }
                   @{$unified_info{scripts}})
                   @{$unified_info{scripts}})
 -}
 -}
+INSTALL_EXPORTERS_CMAKE={-
+        join(" ", map { quotify1($_) }
+                  grep { $unified_info{attributes}->{generate}->{$_}->{exporter} eq 'cmake'}
+                  sort keys %{$unified_info{generate}})
+-}
 IMAGEDOCS1={- our @IMAGEDOCS1 = @{$unified_info{imagedocs}->{man1}};
 IMAGEDOCS1={- our @IMAGEDOCS1 = @{$unified_info{imagedocs}->{man1}};
              join(" ", @IMAGEDOCS1) -}
              join(" ", @IMAGEDOCS1) -}
 IMAGEDOCS3={- our @IMAGEDOCS3 = @{$unified_info{imagedocs}->{man3}};
 IMAGEDOCS3={- our @IMAGEDOCS3 = @{$unified_info{imagedocs}->{man3}};
@@ -249,6 +254,8 @@ MODULESDIR=$(MODULESDIR_dev)$(MODULESDIR_dir)
 libdir={- file_name_is_absolute($libdir)
 libdir={- file_name_is_absolute($libdir)
           ? $libdir : '$(INSTALLTOP)\$(LIBDIR)' -}
           ? $libdir : '$(INSTALLTOP)\$(LIBDIR)' -}
 
 
+CMAKECONFIGDIR=$(libdir)\cmake\OpenSSL
+
 ##### User defined commands and flags ################################
 ##### User defined commands and flags ################################
 
 
 CC="{- $config{CC} -}"
 CC="{- $config{CC} -}"
@@ -559,6 +566,8 @@ install_dev: install_runtime_libs
 	@"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_LIBS) "$(libdir)"
 	@"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_LIBS) "$(libdir)"
 	@if "$(SHLIBS)"=="" \
 	@if "$(SHLIBS)"=="" \
 	 "$(PERL)" "$(SRCDIR)\util\copy.pl" ossl_static.pdb "$(libdir)"
 	 "$(PERL)" "$(SRCDIR)\util\copy.pl" ossl_static.pdb "$(libdir)"
+	@"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(CMAKECONFIGDIR)"
+	@"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_EXPORTERS_CMAKE) "$(CMAKECONFIGDIR)"
 
 
 uninstall_dev:
 uninstall_dev:
 
 

+ 13 - 1
libs/openssl/Configure

@@ -385,6 +385,12 @@ if (defined env($local_config_envname)) {
     }
     }
 }
 }
 
 
+# Fail if no configuration is apparent
+if (!%table) {
+    print "Failed to find any os/compiler configurations. Please make sure the Configurations directory is included.\n";
+    &usage;
+}
+
 # Save away perl command information
 # Save away perl command information
 $config{perl_cmd} = $^X;
 $config{perl_cmd} = $^X;
 $config{perl_version} = $Config{version};
 $config{perl_version} = $Config{version};
@@ -485,6 +491,7 @@ my @disablables = (
     "posix-io",
     "posix-io",
     "psk",
     "psk",
     "quic",
     "quic",
+    "unstable-qlog",
     "rc2",
     "rc2",
     "rc4",
     "rc4",
     "rc5",
     "rc5",
@@ -591,7 +598,7 @@ our %disabled = ( # "what"         => "comment"
 my @disable_cascades = (
 my @disable_cascades = (
     # "what"            => [ "cascade", ... ]
     # "what"            => [ "cascade", ... ]
     "bulk"              => [ "shared", "dso",
     "bulk"              => [ "shared", "dso",
-                             "aria", "async", "autoload-config",
+                             "aria", "async", "atexit", "autoload-config",
                              "blake2", "bf", "camellia", "cast", "chacha",
                              "blake2", "bf", "camellia", "cast", "chacha",
                              "cmac", "cms", "cmp", "comp", "ct",
                              "cmac", "cms", "cmp", "comp", "ct",
                              "des", "dgram", "dh", "dsa",
                              "des", "dgram", "dh", "dsa",
@@ -626,6 +633,7 @@ my @disable_cascades = (
     sub { 0 == scalar grep { !$disabled{$_} } @tls }
     sub { 0 == scalar grep { !$disabled{$_} } @tls }
                         => [ "tls" ],
                         => [ "tls" ],
     "tls1_3"            => [ "quic" ],
     "tls1_3"            => [ "quic" ],
+    "quic"              => [ "unstable-qlog" ],
 
 
     "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
     "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
 
 
@@ -1547,6 +1555,10 @@ unless($disabled{threads}) {
     push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS";
     push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS";
 }
 }
 
 
+if ($disabled{"unstable-qlog"}) {
+    $disabled{"qlog"} = 1;
+}
+
 my $no_shared_warn=0;
 my $no_shared_warn=0;
 if (($target{shared_target} // '') eq "")
 if (($target{shared_target} // '') eq "")
         {
         {

+ 12 - 2
libs/openssl/INSTALL.md

@@ -64,6 +64,7 @@ issues and other details, please read one of these:
  * [Notes for Windows platforms](NOTES-WINDOWS.md)
  * [Notes for Windows platforms](NOTES-WINDOWS.md)
  * [Notes for the DOS platform with DJGPP](NOTES-DJGPP.md)
  * [Notes for the DOS platform with DJGPP](NOTES-DJGPP.md)
  * [Notes for the OpenVMS platform](NOTES-VMS.md)
  * [Notes for the OpenVMS platform](NOTES-VMS.md)
+ * [Notes for the HPE NonStop platform](NOTES-NONSTOP.md)
  * [Notes on Perl](NOTES-PERL.md)
  * [Notes on Perl](NOTES-PERL.md)
  * [Notes on Valgrind](NOTES-VALGRIND.md)
  * [Notes on Valgrind](NOTES-VALGRIND.md)
 
 
@@ -141,7 +142,7 @@ Use the following commands to configure, build and test OpenSSL.
 The testing is optional, but recommended if you intend to install
 The testing is optional, but recommended if you intend to install
 OpenSSL for production use.
 OpenSSL for production use.
 
 
-### Unix / Linux / macOS
+### Unix / Linux / macOS / NonStop
 
 
     $ ./Configure
     $ ./Configure
     $ make
     $ make
@@ -198,7 +199,7 @@ the global search path for system libraries.
 Finally, if you plan on using the FIPS module, you need to read the
 Finally, if you plan on using the FIPS module, you need to read the
 [Post-installation Notes](#post-installation-notes) further down.
 [Post-installation Notes](#post-installation-notes) further down.
 
 
-### Unix / Linux / macOS
+### Unix / Linux / macOS / NonStop
 
 
 Depending on your distribution, you need to run the following command as
 Depending on your distribution, you need to run the following command as
 root user or prepend `sudo` to the command:
 root user or prepend `sudo` to the command:
@@ -606,6 +607,7 @@ Do not use `atexit()` in libcrypto builds.
 
 
 `atexit()` has varied semantics between platforms and can cause SIGSEGV in some
 `atexit()` has varied semantics between platforms and can cause SIGSEGV in some
 circumstances. This option disables the atexit registration of OPENSSL_cleanup.
 circumstances. This option disables the atexit registration of OPENSSL_cleanup.
+By default, NonStop configurations use `no-atexit`.
 
 
 ### no-autoalginit
 ### no-autoalginit
 
 
@@ -1082,6 +1084,14 @@ when needed.
 
 
 This is only supported on systems where loading of shared libraries is supported.
 This is only supported on systems where loading of shared libraries is supported.
 
 
+### enable-unstable-qlog
+
+Enables qlog output support for the QUIC protocol. This functionality is
+unstable and implements a draft version of the qlog specification. The qlog
+output from OpenSSL will change in incompatible ways in future, and is not
+subject to any format stability or compatibility guarantees at this time. See
+the manpage openssl-qlog(7) for details.
+
 ### 386
 ### 386
 
 
 In 32-bit x86 builds, use the 80386 instruction set only in assembly modules
 In 32-bit x86 builds, use the 80386 instruction set only in assembly modules

+ 132 - 3
libs/openssl/NEWS.md

@@ -7,6 +7,7 @@ release. For more details please read the CHANGES file.
 OpenSSL Releases
 OpenSSL Releases
 ----------------
 ----------------
 
 
+ - [OpenSSL 3.3](#openssl-33)
  - [OpenSSL 3.2](#openssl-32)
  - [OpenSSL 3.2](#openssl-32)
  - [OpenSSL 3.1](#openssl-31)
  - [OpenSSL 3.1](#openssl-31)
  - [OpenSSL 3.0](#openssl-30)
  - [OpenSSL 3.0](#openssl-30)
@@ -17,12 +18,12 @@ OpenSSL Releases
  - [OpenSSL 1.0.0](#openssl-100)
  - [OpenSSL 1.0.0](#openssl-100)
  - [OpenSSL 0.9.x](#openssl-09x)
  - [OpenSSL 0.9.x](#openssl-09x)
 
 
-OpenSSL 3.2
+OpenSSL 3.3
 -----------
 -----------
 
 
-### Major changes between OpenSSL 3.2.1 and OpenSSL 3.2.2 [4 Jun 2024]
+### Major changes between OpenSSL 3.3.0 and OpenSSL 3.3.1 [4 Jun 2024]
 
 
-OpenSSL 3.2.2 is a security patch release. The most severe CVE fixed in this
+OpenSSL 3.3.1 is a security patch release. The most severe CVE fixed in this
 release is Low.
 release is Low.
 
 
 This release incorporates the following bug fixes and mitigations:
 This release incorporates the following bug fixes and mitigations:
@@ -34,6 +35,132 @@ This release incorporates the following bug fixes and mitigations:
     be very slow
     be very slow
     ([CVE-2024-4603])
     ([CVE-2024-4603])
 
 
+### Major changes between OpenSSL 3.2 and OpenSSL 3.3.0 [9 Apr 2024]
+
+OpenSSL 3.3.0 is a feature release adding significant new functionality to
+OpenSSL.
+
+This release adds the following new features:
+
+  * Support for qlog for tracing QUIC connections has been added
+
+  * Added APIs to allow configuring the negotiated idle timeout for QUIC
+    connections, and to allow determining the number of additional streams
+    that can currently be created for a QUIC connection.
+
+  * Added APIs to allow disabling implicit QUIC event processing for QUIC SSL
+    objects
+
+  * Added APIs to allow querying the size and utilisation of a QUIC stream's
+    write buffer
+
+  * New API `SSL_write_ex2`, which can be used to send an end-of-stream (FIN)
+    condition in an optimised way when using QUIC.
+
+  * Limited support for polling of QUIC connection and stream objects in a
+    non-blocking manner.
+
+  * Added a new EVP_DigestSqueeze() API. This allows SHAKE to squeeze multiple
+    times with different output sizes.
+
+  * Added exporter for CMake on Unix and Windows, alongside the pkg-config
+    exporter.
+
+  * The BLAKE2s hash algorithm matches BLAKE2b's support for configurable
+    output length.
+
+  * The EVP_PKEY_fromdata function has been augmented to allow for the
+    derivation of CRT (Chinese Remainder Theorem) parameters when requested
+
+  * Added API functions SSL_SESSION_get_time_ex(), SSL_SESSION_set_time_ex()
+    using time_t which is Y2038 safe on 32 bit systems when 64 bit time
+    is enabled
+
+  * Unknown entries in TLS SignatureAlgorithms, ClientSignatureAlgorithms
+    config options and the respective calls to SSL[_CTX]_set1_sigalgs() and
+    SSL[_CTX]_set1_client_sigalgs() that start with `?` character are
+    ignored and the configuration will still be used.
+
+  * Added `-set_issuer` and `-set_subject` options to `openssl x509` to
+    override the Issuer and Subject when creating a certificate. The `-subj`
+    option now is an alias for `-set_subject`.
+
+  * Added several new features of CMPv3 defined in RFC 9480 and RFC 9483
+
+  * New option `SSL_OP_PREFER_NO_DHE_KEX`, which allows configuring a TLS1.3
+    server to prefer session resumption using PSK-only key exchange over PSK
+    with DHE, if both are available.
+
+  * New atexit configuration switch, which controls whether the OPENSSL_cleanup
+    is registered when libcrypto is unloaded.
+
+  * Added X509_STORE_get1_objects to avoid issues with the existing
+    X509_STORE_get0_objects API in multi-threaded applications.
+
+This release incorporates the following potentially significant or incompatible
+changes:
+
+  * Applied AES-GCM unroll8 optimisation to Microsoft Azure Cobalt 100
+
+  * Optimized AES-CTR for ARM Neoverse V1 and V2
+
+  * Enable AES and SHA3 optimisations on Applie Silicon M3-based MacOS systems
+    similar to M1/M2.
+
+  * Various optimizations for cryptographic routines using RISC-V vector crypto
+    extensions
+
+  * Added assembly implementation for md5 on loongarch64
+
+  * Accept longer context for TLS 1.2 exporters
+
+  * The activate and soft_load configuration settings for providers in
+    openssl.cnf have been updated to require a value of [1|yes|true|on]
+    (in lower or UPPER case) to enable the setting. Conversely a value
+    of [0|no|false|off] will disable the setting.
+
+  * In `openssl speed`, changed the default hash function used with `hmac` from
+    `md5` to `sha256`.
+
+  * The `-verify` option to the `openssl crl` and `openssl req` will make the
+    program exit with 1 on failure.
+
+  * The d2i_ASN1_GENERALIZEDTIME(), d2i_ASN1_UTCTIME(), ASN1_TIME_check(), and
+    related functions have been augmented to check for a minimum length of
+    the input string, in accordance with ITU-T X.690 section 11.7 and 11.8.
+
+  * OPENSSL_sk_push() and sk_<TYPE>_push() functions now return 0 instead of -1
+    if called with a NULL stack argument.
+
+  * New limit on HTTP response headers is introduced to HTTP client. The
+    default limit is set to 256 header lines.
+
+This release incorporates the following bug fixes and mitigations:
+
+  * The BIO_get_new_index() function can only be called 127 times before it
+    reaches its upper bound of BIO_TYPE_MASK and will now return -1 once its
+    exhausted.
+
+A more detailed list of changes in this release can be found in the
+[CHANGES.md] file.
+
+Users interested in using the new QUIC functionality are encouraged to read the
+[README file for QUIC][README-QUIC.md], which provides links to relevant
+documentation and example code.
+
+As always, bug reports and issues relating to OpenSSL can be [filed on our issue
+tracker][issue tracker].
+
+OpenSSL 3.2
+-----------
+
+### Major changes between OpenSSL 3.2.1 and OpenSSL 3.2.2 [under development]
+
+OpenSSL 3.2.2 is a security patch release. The most severe CVE fixed in this
+release is Low.
+
+This release incorporates the following bug fixes and mitigations:
+
   * Fixed unbounded memory growth with session handling in TLSv1.3
   * Fixed unbounded memory growth with session handling in TLSv1.3
     ([CVE-2024-2511])
     ([CVE-2024-2511])
 
 
@@ -46,8 +173,10 @@ This release incorporates the following bug fixes and mitigations:
 
 
   * Fixed PKCS12 Decoding crashes
   * Fixed PKCS12 Decoding crashes
     ([CVE-2024-0727])
     ([CVE-2024-0727])
+
   * Fixed excessive time spent checking invalid RSA public keys
   * Fixed excessive time spent checking invalid RSA public keys
     ([CVE-2023-6237])
     ([CVE-2023-6237])
+
   * Fixed POLY1305 MAC implementation corrupting vector registers on PowerPC
   * Fixed POLY1305 MAC implementation corrupting vector registers on PowerPC
     CPUs which support PowerISA 2.07
     CPUs which support PowerISA 2.07
     ([CVE-2023-6129])
     ([CVE-2023-6129])

+ 2 - 2
libs/openssl/NOTES-ANDROID.md

@@ -17,8 +17,8 @@ Notes for Android platforms
  Android is a cross-compiled target and you can't rely on `./Configure`
  Android is a cross-compiled target and you can't rely on `./Configure`
  to find out the configuration target for you.  You have to name your
  to find out the configuration target for you.  You have to name your
  target explicitly; there are `android-arm`, `android-arm64`, `android-mips`,
  target explicitly; there are `android-arm`, `android-arm64`, `android-mips`,
- `android-mip64`, `android-x86` and `android-x86_64` (`*MIPS` targets are no
- longer supported with NDK R20+).
+ `android-mip64`, `android-x86`, `android-x86_64` and `android-riscv64`
+ (`*MIPS` targets are no longer supported with NDK R20+).
 
 
  Do not pass --cross-compile-prefix (as you might be tempted), as it
  Do not pass --cross-compile-prefix (as you might be tempted), as it
  will be "calculated" automatically based on chosen platform. However,
  will be "calculated" automatically based on chosen platform. However,

+ 8 - 7
libs/openssl/NOTES-NONSTOP.md

@@ -19,9 +19,7 @@ About c99 compiler
 
 
 The c99 compiler is required for building OpenSSL from source. While c11
 The c99 compiler is required for building OpenSSL from source. While c11
 may work, it has not been broadly tested. c99 is the only compiler
 may work, it has not been broadly tested. c99 is the only compiler
-prerequisite needed to build OpenSSL 3.0 on this platform. You should also
-have the FLOSS package installed on your system. The ITUGLIB FLOSS package
-is the only FLOSS variant that has been broadly tested.
+prerequisite needed to build OpenSSL 3.0 on this platform.
 
 
 Threading Models
 Threading Models
 ----------------
 ----------------
@@ -60,10 +58,13 @@ relating to `atexit()` processing when a shared library is unloaded and when
 the program terminates. This limitation applies to all OpenSSL shared library
 the program terminates. This limitation applies to all OpenSSL shared library
 components.
 components.
 
 
-It is possible to configure the build with `no-atexit` to avoid the SIGSEGV.
-Preferably, you can explicitly call `OPENSSL_cleanup()` from your application.
-It is not mandatory as it just deallocates various global data structures
-OpenSSL allocated.
+A control has been added as of 3.3.x to disable calls to `atexit()` within the
+`libcrypto` builds (specifically in `crypto/init.c`). This switch can be
+controlled using `disable-atexit` or `enable-atexit`, and is disabled by default
+for NonStop builds. If you need to have `atexit()` functionality, set
+`enabled-atexit` when configuring OpenSSL to enable the `atexit()` call to
+register `OPENSSL_cleanup()` automatically. Preferably, you can explicitly call
+`OPENSSL_cleanup()` from your application.
 
 
 About Prefix and OpenSSLDir
 About Prefix and OpenSSLDir
 ---------------------------
 ---------------------------

+ 2 - 2
libs/openssl/NOTES-WINDOWS.md

@@ -1,9 +1,9 @@
 Notes for Windows platforms
 Notes for Windows platforms
 ===========================
 ===========================
 
 
- - [Native builds using Visual C++](#native-builds-using-visual-c++)
+ - [Native builds using Visual C++](#native-builds-using-visual-c)
  - [Native builds using Embarcadero C++Builder](
  - [Native builds using Embarcadero C++Builder](
-   #native-builds-using-embarcadero-c++-builder)
+   #native-builds-using-embarcadero-cbuilder)
  - [Native builds using MinGW](#native-builds-using-mingw)
  - [Native builds using MinGW](#native-builds-using-mingw)
  - [Linking native applications](#linking-native-applications)
  - [Linking native applications](#linking-native-applications)
  - [Hosted builds using Cygwin](#hosted-builds-using-cygwin)
  - [Hosted builds using Cygwin](#hosted-builds-using-cygwin)

+ 2 - 2
libs/openssl/VERSION.dat

@@ -1,6 +1,6 @@
 MAJOR=3
 MAJOR=3
-MINOR=2
-PATCH=2
+MINOR=3
+PATCH=1
 PRE_RELEASE_TAG=
 PRE_RELEASE_TAG=
 BUILD_METADATA=
 BUILD_METADATA=
 RELEASE_DATE="4 Jun 2024"
 RELEASE_DATE="4 Jun 2024"

+ 269 - 93
libs/openssl/apps/cmp.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Nokia 2007-2019
  * Copyright Nokia 2007-2019
  * Copyright Siemens AG 2015-2019
  * Copyright Siemens AG 2015-2019
  *
  *
@@ -86,6 +86,7 @@ static char *opt_srvcert = NULL;
 static char *opt_expect_sender = NULL;
 static char *opt_expect_sender = NULL;
 static int opt_ignore_keyusage = 0;
 static int opt_ignore_keyusage = 0;
 static int opt_unprotected_errors = 0;
 static int opt_unprotected_errors = 0;
+static int opt_no_cache_extracerts = 0;
 static char *opt_srvcertout = NULL;
 static char *opt_srvcertout = NULL;
 static char *opt_extracertsout = NULL;
 static char *opt_extracertsout = NULL;
 static char *opt_cacertsout = NULL;
 static char *opt_cacertsout = NULL;
@@ -112,6 +113,7 @@ static int opt_cmd = -1;
 static char *opt_geninfo = NULL;
 static char *opt_geninfo = NULL;
 static char *opt_infotype_s = NULL;
 static char *opt_infotype_s = NULL;
 static int opt_infotype = NID_undef;
 static int opt_infotype = NID_undef;
+static char *opt_profile = NULL;
 
 
 /* certificate enrollment */
 /* certificate enrollment */
 static char *opt_newkey = NULL;
 static char *opt_newkey = NULL;
@@ -163,6 +165,8 @@ static int opt_repeat = 1;
 static char *opt_reqin = NULL;
 static char *opt_reqin = NULL;
 static int opt_reqin_new_tid = 0;
 static int opt_reqin_new_tid = 0;
 static char *opt_reqout = NULL;
 static char *opt_reqout = NULL;
+static char *opt_reqout_only = NULL;
+static int reqout_only_done = 0;
 static char *opt_rspin = NULL;
 static char *opt_rspin = NULL;
 static int rspin_in_use = 0;
 static int rspin_in_use = 0;
 static char *opt_rspout = NULL;
 static char *opt_rspout = NULL;
@@ -210,7 +214,7 @@ typedef enum OPTION_choice {
     OPT_COMMON,
     OPT_COMMON,
     OPT_CONFIG, OPT_SECTION, OPT_VERBOSITY,
     OPT_CONFIG, OPT_SECTION, OPT_VERBOSITY,
 
 
-    OPT_CMD, OPT_INFOTYPE, OPT_GENINFO,
+    OPT_CMD, OPT_INFOTYPE, OPT_PROFILE, OPT_GENINFO,
 
 
     OPT_NEWKEY, OPT_NEWKEYPASS, OPT_SUBJECT,
     OPT_NEWKEY, OPT_NEWKEYPASS, OPT_SUBJECT,
     OPT_DAYS, OPT_REQEXTS,
     OPT_DAYS, OPT_REQEXTS,
@@ -230,7 +234,7 @@ typedef enum OPTION_choice {
 
 
     OPT_TRUSTED, OPT_UNTRUSTED, OPT_SRVCERT,
     OPT_TRUSTED, OPT_UNTRUSTED, OPT_SRVCERT,
     OPT_EXPECT_SENDER,
     OPT_EXPECT_SENDER,
-    OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS,
+    OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, OPT_NO_CACHE_EXTRACERTS,
     OPT_SRVCERTOUT, OPT_EXTRACERTSOUT, OPT_CACERTSOUT,
     OPT_SRVCERTOUT, OPT_EXTRACERTSOUT, OPT_CACERTSOUT,
     OPT_OLDWITHOLD, OPT_NEWWITHNEW, OPT_NEWWITHOLD, OPT_OLDWITHNEW,
     OPT_OLDWITHOLD, OPT_NEWWITHNEW, OPT_NEWWITHOLD, OPT_OLDWITHNEW,
 
 
@@ -253,7 +257,8 @@ typedef enum OPTION_choice {
 #endif
 #endif
 
 
     OPT_BATCH, OPT_REPEAT,
     OPT_BATCH, OPT_REPEAT,
-    OPT_REQIN, OPT_REQIN_NEW_TID, OPT_REQOUT, OPT_RSPIN, OPT_RSPOUT,
+    OPT_REQIN, OPT_REQIN_NEW_TID, OPT_REQOUT, OPT_REQOUT_ONLY,
+    OPT_RSPIN, OPT_RSPOUT,
     OPT_USE_MOCK_SRV,
     OPT_USE_MOCK_SRV,
 
 
 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
@@ -291,10 +296,12 @@ const OPTIONS cmp_options[] = {
      "InfoType name for requesting specific info in genm, with specific support"},
      "InfoType name for requesting specific info in genm, with specific support"},
     {OPT_MORE_STR, 0, 0,
     {OPT_MORE_STR, 0, 0,
      "for 'caCerts' and 'rootCaCert'"},
      "for 'caCerts' and 'rootCaCert'"},
+    {"profile", OPT_PROFILE, 's',
+     "Certificate profile name to place in generalInfo field of request PKIHeader"},
     {"geninfo", OPT_GENINFO, 's',
     {"geninfo", OPT_GENINFO, 's',
-     "generalInfo integer values to place in request PKIHeader with given OID"},
+     "Comma-separated list of OID and value to place in generalInfo PKIHeader"},
     {OPT_MORE_STR, 0, 0,
     {OPT_MORE_STR, 0, 0,
-     "specified in the form <OID>:int:<n>, e.g. \"1.2.3.4:int:56789\""},
+     "of form <OID>:int:<n> or <OID>:str:<s>, e.g. \'1.2.3.4:int:56789, id-kp:str:name'"},
 
 
     OPT_SECTION("Certificate enrollment"),
     OPT_SECTION("Certificate enrollment"),
     {"newkey", OPT_NEWKEY, 's',
     {"newkey", OPT_NEWKEY, 's',
@@ -405,6 +412,8 @@ const OPTIONS cmp_options[] = {
      "certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf"},
      "certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf"},
     {OPT_MORE_STR, 0, 0,
     {OPT_MORE_STR, 0, 0,
      "WARNING: This setting leads to behavior allowing violation of RFC 4210"},
      "WARNING: This setting leads to behavior allowing violation of RFC 4210"},
+    {"no_cache_extracerts", OPT_NO_CACHE_EXTRACERTS, '-',
+     "Do not keep certificates received in the extraCerts CMP message field"},
     { "srvcertout", OPT_SRVCERTOUT, 's',
     { "srvcertout", OPT_SRVCERTOUT, 's',
       "File to save the server cert used and validated for CMP response protection"},
       "File to save the server cert used and validated for CMP response protection"},
     {"extracertsout", OPT_EXTRACERTSOUT, 's',
     {"extracertsout", OPT_EXTRACERTSOUT, 's',
@@ -496,6 +505,8 @@ const OPTIONS cmp_options[] = {
      "Use fresh transactionID for CMP requests read from -reqin"},
      "Use fresh transactionID for CMP requests read from -reqin"},
     {"reqout", OPT_REQOUT, 's',
     {"reqout", OPT_REQOUT, 's',
      "Save sequence of CMP requests created by the client to file(s)"},
      "Save sequence of CMP requests created by the client to file(s)"},
+    {"reqout_only", OPT_REQOUT_ONLY, 's',
+     "Save first CMP request created by the client to file and exit"},
     {"rspin", OPT_RSPIN, 's',
     {"rspin", OPT_RSPIN, 's',
      "Process sequence of CMP responses provided in file(s), skipping server"},
      "Process sequence of CMP responses provided in file(s), skipping server"},
     {"rspout", OPT_RSPOUT, 's',
     {"rspout", OPT_RSPOUT, 's',
@@ -587,7 +598,7 @@ typedef union {
 static varref cmp_vars[] = { /* must be in same order as enumerated above! */
 static varref cmp_vars[] = { /* must be in same order as enumerated above! */
     {&opt_config}, {&opt_section}, {(char **)&opt_verbosity},
     {&opt_config}, {&opt_section}, {(char **)&opt_verbosity},
 
 
-    {&opt_cmd_s}, {&opt_infotype_s}, {&opt_geninfo},
+    {&opt_cmd_s}, {&opt_infotype_s}, {&opt_profile}, {&opt_geninfo},
 
 
     {&opt_newkey}, {&opt_newkeypass}, {&opt_subject},
     {&opt_newkey}, {&opt_newkeypass}, {&opt_subject},
     {(char **)&opt_days}, {&opt_reqexts},
     {(char **)&opt_days}, {&opt_reqexts},
@@ -609,6 +620,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */
     {&opt_trusted}, {&opt_untrusted}, {&opt_srvcert},
     {&opt_trusted}, {&opt_untrusted}, {&opt_srvcert},
     {&opt_expect_sender},
     {&opt_expect_sender},
     {(char **)&opt_ignore_keyusage}, {(char **)&opt_unprotected_errors},
     {(char **)&opt_ignore_keyusage}, {(char **)&opt_unprotected_errors},
+    {(char **)&opt_no_cache_extracerts},
     {&opt_srvcertout}, {&opt_extracertsout}, {&opt_cacertsout},
     {&opt_srvcertout}, {&opt_extracertsout}, {&opt_cacertsout},
     {&opt_oldwithold}, {&opt_newwithnew}, {&opt_newwithold}, {&opt_oldwithnew},
     {&opt_oldwithold}, {&opt_newwithnew}, {&opt_newwithold}, {&opt_oldwithnew},
 
 
@@ -631,7 +643,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */
 
 
     {(char **)&opt_batch}, {(char **)&opt_repeat},
     {(char **)&opt_batch}, {(char **)&opt_repeat},
     {&opt_reqin}, {(char **)&opt_reqin_new_tid},
     {&opt_reqin}, {(char **)&opt_reqin_new_tid},
-    {&opt_reqout}, {&opt_rspin}, {&opt_rspout},
+    {&opt_reqout}, {&opt_reqout_only}, {&opt_rspin}, {&opt_rspout},
 
 
     {(char **)&opt_use_mock_srv},
     {(char **)&opt_use_mock_srv},
 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
@@ -807,6 +819,14 @@ static OSSL_CMP_MSG *read_write_req_resp(OSSL_CMP_CTX *ctx,
     OSSL_CMP_PKIHEADER *hdr;
     OSSL_CMP_PKIHEADER *hdr;
     const char *prev_opt_rspin = opt_rspin;
     const char *prev_opt_rspin = opt_rspin;
 
 
+    if (opt_reqout_only != NULL) {
+        if (OSSL_CMP_MSG_write(opt_reqout_only, req) < 0)
+            CMP_err1("cannot write request PKIMessage to file '%s'",
+                     opt_reqout_only);
+        else
+            reqout_only_done = 1;
+        return NULL; /* stop at this point, not contacting any server */
+    }
     if (opt_reqout != NULL && !write_PKIMESSAGE(req, &opt_reqout))
     if (opt_reqout != NULL && !write_PKIMESSAGE(req, &opt_reqout))
         goto err;
         goto err;
     if (opt_reqin != NULL && opt_rspin == NULL) {
     if (opt_reqin != NULL && opt_rspin == NULL) {
@@ -1123,7 +1143,7 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine)
     if (!setup_cert(srv_ctx, opt_ref_cert, opt_otherpass,
     if (!setup_cert(srv_ctx, opt_ref_cert, opt_otherpass,
                     "reference cert to be expected by the mock server",
                     "reference cert to be expected by the mock server",
                     (add_X509_fn_t)ossl_cmp_mock_srv_set1_refCert))
                     (add_X509_fn_t)ossl_cmp_mock_srv_set1_refCert))
-            goto err;
+        goto err;
     if (opt_rsp_cert == NULL) {
     if (opt_rsp_cert == NULL) {
         CMP_warn("no -rsp_cert given for mock server");
         CMP_warn("no -rsp_cert given for mock server");
     } else {
     } else {
@@ -1235,9 +1255,6 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx)
         }
         }
     }
     }
 
 
-    if (opt_ignore_keyusage)
-        (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_IGNORE_KEYUSAGE, 1);
-
     if (opt_unprotected_errors)
     if (opt_unprotected_errors)
         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1);
         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1);
 
 
@@ -1541,6 +1558,48 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
     return 1;
     return 1;
 }
 }
 
 
+static int set_fallback_pubkey(OSSL_CMP_CTX *ctx)
+{
+    char *file = opt_reqin, *end = file, bak;
+    OSSL_CMP_MSG *req;
+    const X509_PUBKEY *pubkey;
+    EVP_PKEY *pkey;
+    EVP_PKEY *pkey1;
+    int res = 0;
+
+    /* temporarily separate first file name in opt_reqin */
+    while (*end != ',' && !isspace(_UC(*end)) && *end != '\0')
+        end++;
+    bak = *end;
+    *end = '\0';
+    req = OSSL_CMP_MSG_read(file, app_get0_libctx(), app_get0_propq());
+    *end = bak;
+
+    if (req == NULL) {
+        CMP_err1("failed to load ir/cr/kur file '%s' attempting to get fallback public key",
+                 file);
+        return 0;
+    }
+    if ((pubkey = OSSL_CMP_MSG_get0_certreq_publickey(req)) == NULL
+        || (pkey = X509_PUBKEY_get0(pubkey)) == NULL) {
+        CMP_err1("failed to get fallback public key from ir/cr/kur file '%s'",
+                 file);
+        goto err;
+    }
+    pkey1 = EVP_PKEY_dup(pkey);
+    if (pkey == NULL || !OSSL_CMP_CTX_set0_newPkey(ctx, 0 /* priv */, pkey1)) {
+        EVP_PKEY_free(pkey1);
+        CMP_err1("failed to get fallback public key obtained from ir/cr/kur file '%s'",
+                 file);
+        goto err;
+    }
+    res = 1;
+
+ err:
+    OSSL_CMP_MSG_free(req);
+    return res;
+}
+
 /*
 /*
  * Set up IR/CR/P10CR/KUR/CertConf/RR/GENM specific parts of the OSSL_CMP_CTX
  * Set up IR/CR/P10CR/KUR/CertConf/RR/GENM specific parts of the OSSL_CMP_CTX
  * based on options from CLI and/or config file.
  * based on options from CLI and/or config file.
@@ -1560,26 +1619,28 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
     if (!set_name(opt_issuer, OSSL_CMP_CTX_set1_issuer, ctx, "issuer"))
     if (!set_name(opt_issuer, OSSL_CMP_CTX_set1_issuer, ctx, "issuer"))
         return 0;
         return 0;
     if (opt_cmd == CMP_IR || opt_cmd == CMP_CR || opt_cmd == CMP_KUR) {
     if (opt_cmd == CMP_IR || opt_cmd == CMP_CR || opt_cmd == CMP_KUR) {
-        if (opt_newkey == NULL
+        if (opt_reqin == NULL && opt_newkey == NULL
             && opt_key == NULL && opt_csr == NULL && opt_oldcert == NULL) {
             && opt_key == NULL && opt_csr == NULL && opt_oldcert == NULL) {
-            CMP_err("missing -newkey (or -key) to be certified and no -csr, -oldcert, or -cert given for fallback public key");
+            CMP_err("missing -newkey (or -key) to be certified and no -csr, -oldcert, -cert, or -reqin option given, which could provide fallback public key");
             return 0;
             return 0;
         }
         }
         if (opt_newkey == NULL
         if (opt_newkey == NULL
             && opt_popo != OSSL_CRMF_POPO_NONE
             && opt_popo != OSSL_CRMF_POPO_NONE
             && opt_popo != OSSL_CRMF_POPO_RAVERIFIED) {
             && opt_popo != OSSL_CRMF_POPO_RAVERIFIED) {
             if (opt_csr != NULL) {
             if (opt_csr != NULL) {
-                CMP_err1("no -newkey option given with private key for POPO, -csr option only provides public key%s",
-                        opt_key == NULL ? "" :
-                        ", and -key option superseded by -csr");
+                CMP_err1("no -newkey option given with private key for POPO, -csr option provides just public key%s",
+                         opt_key == NULL ? "" :
+                         ", and -key option superseded by -csr");
+                if (opt_reqin != NULL)
+                    CMP_info("since -reqin is used, may use -popo -1 or -popo 0 to disable the needless generation of a POPO");
                 return 0;
                 return 0;
             }
             }
             if (opt_key == NULL) {
             if (opt_key == NULL) {
-                CMP_err("missing -newkey (or -key) option for POPO");
+                CMP_err("missing -newkey (or -key) option for key to be certified and for POPO");
                 return 0;
                 return 0;
             }
             }
         }
         }
-        if (opt_certout == NULL) {
+        if (opt_certout == NULL && opt_reqout_only == NULL) {
             CMP_err("-certout not given, nowhere to save newly enrolled certificate");
             CMP_err("-certout not given, nowhere to save newly enrolled certificate");
             return 0;
             return 0;
         }
         }
@@ -1594,7 +1655,8 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
                 if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject"))
                 if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject"))
                     return 0;
                     return 0;
             } else {
             } else {
-                CMP_warn1("-subject %s since sender is taken from -ref or -cert", msg);
+                CMP_warn1("-subject %s since sender is taken from -ref or -cert",
+                          msg);
             }
             }
         }
         }
         if (opt_issuer != NULL && opt_cmd != CMP_RR)
         if (opt_issuer != NULL && opt_cmd != CMP_RR)
@@ -1678,7 +1740,7 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
 
 
     if (opt_recipient == NULL && opt_srvcert == NULL && opt_issuer == NULL
     if (opt_recipient == NULL && opt_srvcert == NULL && opt_issuer == NULL
             && opt_oldcert == NULL && opt_cert == NULL)
             && opt_oldcert == NULL && opt_cert == NULL)
-        CMP_warn("missing -recipient, -srvcert, -issuer, -oldcert or -cert; recipient will be set to \"NULL-DN\"");
+        CMP_warn("missing -recipient, -srvcert, -issuer, -oldcert or -cert; recipient for any requests not covered by -reqin will be set to \"NULL-DN\"");
 
 
     if (opt_cmd == CMP_P10CR || opt_cmd == CMP_RR || opt_cmd == CMP_GENM) {
     if (opt_cmd == CMP_P10CR || opt_cmd == CMP_RR || opt_cmd == CMP_GENM) {
         const char *msg = "option is ignored for 'p10cr', 'rr', and 'genm' commands";
         const char *msg = "option is ignored for 'p10cr', 'rr', and 'genm' commands";
@@ -1718,6 +1780,10 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
             EVP_PKEY_free(pkey);
             EVP_PKEY_free(pkey);
             return 0;
             return 0;
         }
         }
+    } else if (opt_reqin != NULL
+               && opt_key == NULL && opt_csr == NULL && opt_oldcert == NULL) {
+        if (!set_fallback_pubkey(ctx))
+            return 0;
     }
     }
 
 
     if (opt_days > 0
     if (opt_days > 0
@@ -1791,9 +1857,11 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
         char *next = next_item(opt_policy_oids);
         char *next = next_item(opt_policy_oids);
 
 
         if ((policy = OBJ_txt2obj(opt_policy_oids, 1)) == 0) {
         if ((policy = OBJ_txt2obj(opt_policy_oids, 1)) == 0) {
-            CMP_err1("unknown policy OID '%s'", opt_policy_oids);
+            CMP_err1("Invalid -policy_oids arg '%s'", opt_policy_oids);
             return 0;
             return 0;
         }
         }
+        if (OBJ_obj2nid(policy) == NID_undef)
+            CMP_warn1("Unknown -policy_oids arg: %.40s", opt_policy_oids);
 
 
         if ((pinfo = POLICYINFO_new()) == NULL) {
         if ((pinfo = POLICYINFO_new()) == NULL) {
             ASN1_OBJECT_free(policy);
             ASN1_OBJECT_free(policy);
@@ -1808,7 +1876,6 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
         }
         }
         opt_policy_oids = next;
         opt_policy_oids = next;
     }
     }
-
     if (opt_popo >= OSSL_CRMF_POPO_NONE)
     if (opt_popo >= OSSL_CRMF_POPO_NONE)
         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POPO_METHOD, opt_popo);
         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POPO_METHOD, opt_popo);
 
 
@@ -1837,64 +1904,127 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
     return 0;
     return 0;
 }
 }
 
 
-static int handle_opt_geninfo(OSSL_CMP_CTX *ctx)
+static int add_certProfile(OSSL_CMP_CTX *ctx, const char *name)
 {
 {
-    long value;
-    ASN1_OBJECT *type;
-    ASN1_INTEGER *aint;
-    ASN1_TYPE *val;
-    OSSL_CMP_ITAV *itav;
-    char *endstr;
-    char *valptr = strchr(opt_geninfo, ':');
+    OSSL_CMP_ITAV *itav = NULL;
+    STACK_OF(ASN1_UTF8STRING) *sk;
+    ASN1_UTF8STRING *utf8string;
 
 
-    if (valptr == NULL) {
-        CMP_err("missing ':' in -geninfo option");
+    if (ctx == NULL || name == NULL)
         return 0;
         return 0;
-    }
-    valptr[0] = '\0';
-    valptr++;
 
 
-    if (!CHECK_AND_SKIP_CASE_PREFIX(valptr, "int:")) {
-        CMP_err("missing 'int:' in -geninfo option");
+    if ((sk = sk_ASN1_UTF8STRING_new_reserve(NULL, 1)) == NULL)
         return 0;
         return 0;
-    }
+   if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
+       goto err;
+   if (!ASN1_STRING_set(utf8string, name, (int)strlen(name))) {
+       ASN1_STRING_free(utf8string);
+       goto err;
+   }
+   /* Due to sk_ASN1_UTF8STRING_new_reserve(NULL, 1), this surely succeeds: */
+   (void)sk_ASN1_UTF8STRING_push(sk, utf8string);
+   if ((itav = OSSL_CMP_ITAV_new0_certProfile(sk)) == NULL)
+       goto err;
+   if (OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav))
+       return 1;
+   OSSL_CMP_ITAV_free(itav);
+   return 0;
 
 
-    value = strtol(valptr, &endstr, 10);
-    if (endstr == valptr || *endstr != '\0') {
-        CMP_err("cannot parse int in -geninfo option");
-        return 0;
-    }
+ err:
+    sk_ASN1_UTF8STRING_pop_free(sk, ASN1_UTF8STRING_free);
+    return 0;
+}
 
 
-    type = OBJ_txt2obj(opt_geninfo, 1);
-    if (type == NULL) {
-        CMP_err("cannot parse OID in -geninfo option");
-        return 0;
-    }
+static int handle_opt_geninfo(OSSL_CMP_CTX *ctx)
+{
+    ASN1_OBJECT *obj = NULL;
+    ASN1_TYPE *type = NULL;
+    long value;
+    ASN1_INTEGER *aint = NULL;
+    ASN1_UTF8STRING *text = NULL;
+    OSSL_CMP_ITAV *itav;
+    char *ptr = opt_geninfo, *oid, *end;
+
+    do {
+        while (isspace(_UC(*ptr)))
+            ptr++;
+        oid = ptr;
+        if ((ptr = strchr(oid, ':')) == NULL) {
+            CMP_err1("Missing ':' in -geninfo arg %.40s", oid);
+            return 0;
+        }
+        *ptr++ = '\0';
+        if ((obj = OBJ_txt2obj(oid, 0)) == NULL) {
+            CMP_err1("Invalid OID in -geninfo arg %.40s", oid);
+            return 0;
+        }
+        if (OBJ_obj2nid(obj) == NID_undef)
+            CMP_warn1("Unknown OID in -geninfo arg: %.40s", oid);
+        if ((type = ASN1_TYPE_new()) == NULL)
+            goto oom;
 
 
-    if ((aint = ASN1_INTEGER_new()) == NULL)
-        goto oom;
+        if (CHECK_AND_SKIP_CASE_PREFIX(ptr, "int:")) {
+            value = strtol(ptr, &end, 10);
+            if (end == ptr) {
+                CMP_err1("Cannot parse int in -geninfo arg %.40s", ptr);
+                goto err;
+            }
+            ptr = end;
+            if (*ptr != '\0') {
+                if (*ptr != ',') {
+                    CMP_err1("Missing ',' or end of -geninfo arg after int at %.40s",
+                        ptr);
+                    goto err;
+                }
+                ptr++;
+            }
 
 
-    val = ASN1_TYPE_new();
-    if (!ASN1_INTEGER_set(aint, value) || val == NULL) {
-        ASN1_INTEGER_free(aint);
-        goto oom;
-    }
-    ASN1_TYPE_set(val, V_ASN1_INTEGER, aint);
-    itav = OSSL_CMP_ITAV_create(type, val);
-    if (itav == NULL) {
-        ASN1_TYPE_free(val);
-        goto oom;
-    }
+            if ((aint = ASN1_INTEGER_new()) == NULL
+                    || !ASN1_INTEGER_set(aint, value))
+                goto oom;
+            ASN1_TYPE_set(type, V_ASN1_INTEGER, aint);
+            aint = NULL;
+
+        } else if (CHECK_AND_SKIP_CASE_PREFIX(ptr, "str:")) {
+            end = strchr(ptr, ',');
+            if (end == NULL)
+                end = ptr + strlen(ptr);
+            else
+                *end++ = '\0';
+            if ((text = ASN1_UTF8STRING_new()) == NULL
+                    || !ASN1_STRING_set(text, ptr, -1))
+                goto oom;
+            ptr = end;
+            ASN1_TYPE_set(type, V_ASN1_UTF8STRING, text);
+            text = NULL;
 
 
-    if (!OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav)) {
-        OSSL_CMP_ITAV_free(itav);
-        return 0;
-    }
+        } else {
+            CMP_err1("Missing 'int:' or 'str:' in -geninfo arg %.40s", ptr);
+            goto err;
+        }
+
+        if ((itav = OSSL_CMP_ITAV_create(obj, type)) == NULL) {
+            CMP_err("Unable to create 'OSSL_CMP_ITAV' structure");
+            goto err;
+        }
+        obj = NULL;
+        type = NULL;
+
+        if (!OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav)) {
+            CMP_err("Failed to add ITAV for geninfo of the PKI message header");
+            OSSL_CMP_ITAV_free(itav);
+            return 0;
+        }
+    } while (*ptr != '\0');
     return 1;
     return 1;
 
 
  oom:
  oom:
-    ASN1_OBJECT_free(type);
     CMP_err("out of memory");
     CMP_err("out of memory");
+ err:
+    ASN1_OBJECT_free(obj);
+    ASN1_TYPE_free(type);
+    ASN1_INTEGER_free(aint);
+    ASN1_UTF8STRING_free(text);
     return 0;
     return 0;
 }
 }
 
 
@@ -1916,9 +2046,11 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
     char server_buf[200] = "mock server";
     char server_buf[200] = "mock server";
     char proxy_buf[200] = "";
     char proxy_buf[200] = "";
 
 
+    if (!opt_use_mock_srv)
+        strcpy(server_buf, "no server");
     if (!opt_use_mock_srv && opt_rspin == NULL) { /* note: -port is not given */
     if (!opt_use_mock_srv && opt_rspin == NULL) { /* note: -port is not given */
 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
-        if (opt_server == NULL) {
+        if (opt_server == NULL && opt_reqout_only == NULL) {
             CMP_err("missing -server or -use_mock_srv or -rspin option");
             CMP_err("missing -server or -use_mock_srv or -rspin option");
             goto err;
             goto err;
         }
         }
@@ -2078,14 +2210,14 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
 
 
     if (opt_geninfo != NULL && !handle_opt_geninfo(ctx))
     if (opt_geninfo != NULL && !handle_opt_geninfo(ctx))
         goto err;
         goto err;
+    if (opt_profile != NULL && !add_certProfile(ctx, opt_profile))
+        goto err;
 
 
     /* not printing earlier, to minimize confusion in case setup fails before */
     /* not printing earlier, to minimize confusion in case setup fails before */
-    if (opt_rspin != NULL)
-        CMP_info2("will contact %s%s "
-                  "only if -rspin argument gives too few filenames",
-                  server_buf, proxy_buf);
-    else
-        CMP_info2("will contact %s%s", server_buf, proxy_buf);
+    if (opt_reqout_only == NULL)
+        CMP_info3("will contact %s%s%s ", server_buf, proxy_buf,
+                  opt_rspin == NULL ? "" :
+                  " only if -rspin argument gives too few filenames");
 
 
     ret = 1;
     ret = 1;
 
 
@@ -2571,6 +2703,9 @@ static int get_opts(int argc, char **argv)
         case OPT_UNPROTECTED_ERRORS:
         case OPT_UNPROTECTED_ERRORS:
             opt_unprotected_errors = 1;
             opt_unprotected_errors = 1;
             break;
             break;
+        case OPT_NO_CACHE_EXTRACERTS:
+            opt_no_cache_extracerts = 1;
+            break;
         case OPT_SRVCERTOUT:
         case OPT_SRVCERTOUT:
             opt_srvcertout = opt_str();
             opt_srvcertout = opt_str();
             break;
             break;
@@ -2603,6 +2738,9 @@ static int get_opts(int argc, char **argv)
         case OPT_INFOTYPE:
         case OPT_INFOTYPE:
             opt_infotype_s = opt_str();
             opt_infotype_s = opt_str();
             break;
             break;
+        case OPT_PROFILE:
+            opt_profile = opt_str();
+            break;
         case OPT_GENINFO:
         case OPT_GENINFO:
             opt_geninfo = opt_str();
             opt_geninfo = opt_str();
             break;
             break;
@@ -2719,6 +2857,9 @@ static int get_opts(int argc, char **argv)
         case OPT_REQOUT:
         case OPT_REQOUT:
             opt_reqout = opt_str();
             opt_reqout = opt_str();
             break;
             break;
+        case OPT_REQOUT_ONLY:
+            opt_reqout_only = opt_str();
+            break;
         case OPT_RSPIN:
         case OPT_RSPIN:
             opt_rspin = opt_str();
             opt_rspin = opt_str();
             break;
             break;
@@ -3028,25 +3169,17 @@ static int do_genm(OSSL_CMP_CTX *ctx)
     }
     }
 }
 }
 
 
-int cmp_main(int argc, char **argv)
+static int handle_opts_upfront(int argc, char **argv)
 {
 {
-    char *configfile = NULL;
     int i;
     int i;
-    X509 *newcert = NULL;
-    ENGINE *engine = NULL;
-    OSSL_CMP_CTX *srv_cmp_ctx = NULL;
-    int ret = 0; /* default: failure */
 
 
     prog = opt_appname(argv[0]);
     prog = opt_appname(argv[0]);
     if (argc <= 1) {
     if (argc <= 1) {
         opt_help(cmp_options);
         opt_help(cmp_options);
-        goto err;
+        return 0;
     }
     }
 
 
-    /*
-     * handle options -config, -section, and -verbosity upfront
-     * to take effect for other options
-     */
+    /* handle -config, -section, and -verbosity to take effect for other opts */
     for (i = 1; i < argc - 1; i++) {
     for (i = 1; i < argc - 1; i++) {
         if (*argv[i] == '-') {
         if (*argv[i] == '-') {
             if (!strcmp(argv[i] + 1, cmp_options[OPT_CONFIG - OPT_HELP].name))
             if (!strcmp(argv[i] + 1, cmp_options[OPT_CONFIG - OPT_HELP].name))
@@ -3057,11 +3190,25 @@ int cmp_main(int argc, char **argv)
             else if (strcmp(argv[i] + 1,
             else if (strcmp(argv[i] + 1,
                             cmp_options[OPT_VERBOSITY - OPT_HELP].name) == 0
                             cmp_options[OPT_VERBOSITY - OPT_HELP].name) == 0
                      && !set_verbosity(atoi(argv[++i])))
                      && !set_verbosity(atoi(argv[++i])))
-                goto err;
+                return 0;
         }
         }
     }
     }
     if (opt_section[0] == '\0') /* empty string */
     if (opt_section[0] == '\0') /* empty string */
         opt_section = DEFAULT_SECTION;
         opt_section = DEFAULT_SECTION;
+    return 1;
+}
+
+int cmp_main(int argc, char **argv)
+{
+    char *configfile = NULL;
+    int i;
+    X509 *newcert = NULL;
+    ENGINE *engine = NULL;
+    OSSL_CMP_CTX *srv_cmp_ctx = NULL;
+    int ret = 0; /* default: failure */
+
+    if (!handle_opts_upfront(argc, argv))
+        goto err;
 
 
     vpm = X509_VERIFY_PARAM_new();
     vpm = X509_VERIFY_PARAM_new();
     if (vpm == NULL) {
     if (vpm == NULL) {
@@ -3108,6 +3255,10 @@ int cmp_main(int argc, char **argv)
     }
     }
     (void)BIO_flush(bio_err); /* prevent interference with opt_help() */
     (void)BIO_flush(bio_err); /* prevent interference with opt_help() */
 
 
+    cmp_ctx = OSSL_CMP_CTX_new(app_get0_libctx(), app_get0_propq());
+    if (cmp_ctx == NULL)
+        goto err;
+
     ret = get_opts(argc, argv);
     ret = get_opts(argc, argv);
     if (ret <= 0)
     if (ret <= 0)
         goto err;
         goto err;
@@ -3128,9 +3279,6 @@ int cmp_main(int argc, char **argv)
         }
         }
     }
     }
 
 
-    cmp_ctx = OSSL_CMP_CTX_new(app_get0_libctx(), app_get0_propq());
-    if (cmp_ctx == NULL)
-        goto err;
     OSSL_CMP_CTX_set_log_verbosity(cmp_ctx, opt_verbosity);
     OSSL_CMP_CTX_set_log_verbosity(cmp_ctx, opt_verbosity);
     if (!OSSL_CMP_CTX_set_log_cb(cmp_ctx, print_to_bio_out)) {
     if (!OSSL_CMP_CTX_set_log_cb(cmp_ctx, print_to_bio_out)) {
         CMP_err1("cannot set up error reporting and logging for %s", prog);
         CMP_err1("cannot set up error reporting and logging for %s", prog);
@@ -3170,11 +3318,17 @@ int cmp_main(int argc, char **argv)
     }
     }
 #endif
 #endif
 
 
-    if (opt_use_mock_srv
+    if (opt_ignore_keyusage)
+        (void)OSSL_CMP_CTX_set_option(cmp_ctx, OSSL_CMP_OPT_IGNORE_KEYUSAGE, 1);
+    if (opt_no_cache_extracerts)
+        (void)OSSL_CMP_CTX_set_option(cmp_ctx, OSSL_CMP_OPT_NO_CACHE_EXTRACERTS,
+                                      1);
+
+    if (opt_reqout_only == NULL && (opt_use_mock_srv
 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
-        || opt_port != NULL
+                                    || opt_port != NULL
 #endif
 #endif
-        ) {
+                                    )) {
         OSSL_CMP_SRV_CTX *srv_ctx;
         OSSL_CMP_SRV_CTX *srv_ctx;
 
 
         if ((srv_ctx = setup_srv_ctx(engine)) == NULL)
         if ((srv_ctx = setup_srv_ctx(engine)) == NULL)
@@ -3201,6 +3355,23 @@ int cmp_main(int argc, char **argv)
 
 
     /* act as CMP client, possibly using internal mock server */
     /* act as CMP client, possibly using internal mock server */
 
 
+    if (opt_reqout_only != NULL) {
+        const char *msg = "option is ignored since -reqout_only option is given";
+
+#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
+        if (opt_server != NULL)
+            CMP_warn1("-server %s", msg);
+#endif
+        if (opt_use_mock_srv)
+            CMP_warn1("-use_mock_srv %s", msg);
+        if (opt_reqout != NULL)
+            CMP_warn1("-reqout %s", msg);
+        if (opt_rspin != NULL)
+            CMP_warn1("-rspin %s", msg);
+        if (opt_rspout != NULL)
+            CMP_warn1("-rspout %s", msg);
+        opt_reqout = opt_reqout_only;
+    }
     if (opt_rspin != NULL) {
     if (opt_rspin != NULL) {
         if (opt_server != NULL)
         if (opt_server != NULL)
             CMP_warn("-server option is not used if enough filenames given for -rspin");
             CMP_warn("-server option is not used if enough filenames given for -rspin");
@@ -3245,8 +3416,13 @@ int cmp_main(int argc, char **argv)
             break;
             break;
         }
         }
         if (OSSL_CMP_CTX_get_status(cmp_ctx) < OSSL_CMP_PKISTATUS_accepted) {
         if (OSSL_CMP_CTX_get_status(cmp_ctx) < OSSL_CMP_PKISTATUS_accepted) {
+            /* we got no response, maybe even did not send request */
             ret = 0;
             ret = 0;
-            goto err; /* we got no response, maybe even did not send request */
+            if (reqout_only_done) {
+                ERR_clear_error();
+                ret = 1;
+            }
+            goto err;
         }
         }
         print_status();
         print_status();
         if (!save_cert_or_delete(OSSL_CMP_CTX_get0_validatedSrvCert(cmp_ctx),
         if (!save_cert_or_delete(OSSL_CMP_CTX_get0_validatedSrvCert(cmp_ctx),

+ 4 - 3
libs/openssl/apps/crl.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -248,9 +248,10 @@ int crl_main(int argc, char **argv)
         EVP_PKEY_free(pkey);
         EVP_PKEY_free(pkey);
         if (i < 0)
         if (i < 0)
             goto end;
             goto end;
-        if (i == 0)
+        if (i == 0) {
             BIO_printf(bio_err, "verify failure\n");
             BIO_printf(bio_err, "verify failure\n");
-        else
+	    goto end;
+        } else
             BIO_printf(bio_err, "verify OK\n");
             BIO_printf(bio_err, "verify OK\n");
     }
     }
 
 

+ 2 - 1
libs/openssl/apps/enc.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -593,6 +593,7 @@ int enc_main(int argc, char **argv)
         }
         }
         if (hiv != NULL) {
         if (hiv != NULL) {
             int siz = EVP_CIPHER_get_iv_length(cipher);
             int siz = EVP_CIPHER_get_iv_length(cipher);
+
             if (siz == 0) {
             if (siz == 0) {
                 BIO_printf(bio_err, "warning: iv not used by this cipher\n");
                 BIO_printf(bio_err, "warning: iv not used by this cipher\n");
             } else if (!set_hex(hiv, iv, siz)) {
             } else if (!set_hex(hiv, iv, siz)) {

+ 5 - 2
libs/openssl/apps/engine.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -251,7 +251,7 @@ static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
         cmd = sk_OPENSSL_STRING_value(cmds, loop);
         cmd = sk_OPENSSL_STRING_value(cmds, loop);
         res = 1;                /* assume success */
         res = 1;                /* assume success */
         /* Check if this command has no ":arg" */
         /* Check if this command has no ":arg" */
-        if ((arg = strstr(cmd, ":")) == NULL) {
+        if ((arg = strchr(cmd, ':')) == NULL) {
             if (!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
             if (!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
                 res = 0;
                 res = 0;
         } else {
         } else {
@@ -405,6 +405,9 @@ int engine_main(int argc, char **argv)
                 if (ENGINE_get_RSA(e) != NULL
                 if (ENGINE_get_RSA(e) != NULL
                     && !append_buf(&cap_buf, &cap_size, "RSA"))
                     && !append_buf(&cap_buf, &cap_size, "RSA"))
                     goto end;
                     goto end;
+                if (ENGINE_get_EC(e) != NULL
+                    && !append_buf(&cap_buf, &cap_size, "EC"))
+                    goto end;
                 if (ENGINE_get_DSA(e) != NULL
                 if (ENGINE_get_DSA(e) != NULL
                     && !append_buf(&cap_buf, &cap_size, "DSA"))
                     && !append_buf(&cap_buf, &cap_size, "DSA"))
                     goto end;
                     goto end;

+ 10 - 2
libs/openssl/apps/genpkey.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -24,7 +24,7 @@ typedef enum OPTION_choice {
     OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE,
     OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE,
     OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER,
     OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER,
     OPT_VERBOSE, OPT_QUIET, OPT_CONFIG, OPT_OUTPUBKEY,
     OPT_VERBOSE, OPT_QUIET, OPT_CONFIG, OPT_OUTPUBKEY,
-    OPT_PROV_ENUM
+    OPT_PROV_ENUM, OPT_R_ENUM
 } OPTION_CHOICE;
 } OPTION_CHOICE;
 
 
 const OPTIONS genpkey_options[] = {
 const OPTIONS genpkey_options[] = {
@@ -51,6 +51,7 @@ const OPTIONS genpkey_options[] = {
     {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"},
     {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"},
 
 
     OPT_PROV_OPTIONS,
     OPT_PROV_OPTIONS,
+    OPT_R_OPTIONS,
 
 
     /* This is deliberately last. */
     /* This is deliberately last. */
     {OPT_HELP_STR, 1, 1,
     {OPT_HELP_STR, 1, 1,
@@ -188,6 +189,10 @@ int genpkey_main(int argc, char **argv)
             if (!opt_provider(o))
             if (!opt_provider(o))
                 goto end;
                 goto end;
             break;
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         }
         }
     }
     }
 
 
@@ -195,6 +200,9 @@ int genpkey_main(int argc, char **argv)
     if (!opt_check_rest_arg(NULL))
     if (!opt_check_rest_arg(NULL))
         goto opthelp;
         goto opthelp;
 
 
+    if (!app_RAND_load())
+        goto end;
+
     /* Fetch cipher, etc. */
     /* Fetch cipher, etc. */
     if (paramfile != NULL) {
     if (paramfile != NULL) {
         if (!init_keygen_file(&ctx, paramfile, e, libctx, app_get0_propq()))
         if (!init_keygen_file(&ctx, paramfile, e, libctx, app_get0_propq()))

+ 5 - 1
libs/openssl/apps/include/opt.h

@@ -157,7 +157,8 @@
         OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \
         OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \
         OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_CLIENTRENEG, \
         OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_CLIENTRENEG, \
         OPT_S_LEGACYCONN, \
         OPT_S_LEGACYCONN, \
-        OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_ALLOW_NO_DHE_KEX, \
+        OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, \
+        OPT_S_ALLOW_NO_DHE_KEX, OPT_S_PREFER_NO_DHE_KEX, \
         OPT_S_PRIORITIZE_CHACHA, \
         OPT_S_PRIORITIZE_CHACHA, \
         OPT_S_STRICT, OPT_S_SIGALGS, OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, \
         OPT_S_STRICT, OPT_S_SIGALGS, OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, \
         OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_CIPHERSUITES, \
         OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_CIPHERSUITES, \
@@ -198,6 +199,8 @@
             "Disallow initial connection to servers that don't support RI"}, \
             "Disallow initial connection to servers that don't support RI"}, \
         {"allow_no_dhe_kex", OPT_S_ALLOW_NO_DHE_KEX, '-', \
         {"allow_no_dhe_kex", OPT_S_ALLOW_NO_DHE_KEX, '-', \
             "In TLSv1.3 allow non-(ec)dhe based key exchange on resumption"}, \
             "In TLSv1.3 allow non-(ec)dhe based key exchange on resumption"}, \
+        {"prefer_no_dhe_kex", OPT_S_PREFER_NO_DHE_KEX, '-', \
+            "In TLSv1.3 prefer non-(ec)dhe over (ec)dhe-based key exchange on resumption"}, \
         {"prioritize_chacha", OPT_S_PRIORITIZE_CHACHA, '-', \
         {"prioritize_chacha", OPT_S_PRIORITIZE_CHACHA, '-', \
             "Prioritize ChaCha ciphers when preferred by clients"}, \
             "Prioritize ChaCha ciphers when preferred by clients"}, \
         {"strict", OPT_S_STRICT, '-', \
         {"strict", OPT_S_STRICT, '-', \
@@ -248,6 +251,7 @@
         case OPT_S_ONRESUMP: \
         case OPT_S_ONRESUMP: \
         case OPT_S_NOLEGACYCONN: \
         case OPT_S_NOLEGACYCONN: \
         case OPT_S_ALLOW_NO_DHE_KEX: \
         case OPT_S_ALLOW_NO_DHE_KEX: \
+        case OPT_S_PREFER_NO_DHE_KEX: \
         case OPT_S_PRIORITIZE_CHACHA: \
         case OPT_S_PRIORITIZE_CHACHA: \
         case OPT_S_STRICT: \
         case OPT_S_STRICT: \
         case OPT_S_SIGALGS: \
         case OPT_S_SIGALGS: \

+ 1 - 16
libs/openssl/apps/lib/apps.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -2952,11 +2952,6 @@ int raw_read_stdin(void *buf, int siz)
     return recv(fileno_stdin(), buf, siz, 0);
     return recv(fileno_stdin(), buf, siz, 0);
 }
 }
 #else
 #else
-# if defined(__TANDEM)
-#  if defined(OPENSSL_TANDEM_FLOSS)
-#   include <floss.h(floss_read)>
-#  endif
-# endif
 int raw_read_stdin(void *buf, int siz)
 int raw_read_stdin(void *buf, int siz)
 {
 {
     return read(fileno_stdin(), buf, siz);
     return read(fileno_stdin(), buf, siz);
@@ -2975,21 +2970,11 @@ int raw_write_stdout(const void *buf, int siz)
 }
 }
 #elif defined(OPENSSL_SYS_TANDEM) && defined(OPENSSL_THREADS) \
 #elif defined(OPENSSL_SYS_TANDEM) && defined(OPENSSL_THREADS) \
     && defined(_SPT_MODEL_)
     && defined(_SPT_MODEL_)
-# if defined(__TANDEM)
-#  if defined(OPENSSL_TANDEM_FLOSS)
-#   include <floss.h(floss_write)>
-#  endif
-# endif
 int raw_write_stdout(const void *buf, int siz)
 int raw_write_stdout(const void *buf, int siz)
 {
 {
     return write(fileno(stdout), (void *)buf, siz);
     return write(fileno(stdout), (void *)buf, siz);
 }
 }
 #else
 #else
-# if defined(__TANDEM)
-#  if defined(OPENSSL_TANDEM_FLOSS)
-#   include <floss.h(floss_write)>
-#  endif
-# endif
 int raw_write_stdout(const void *buf, int siz)
 int raw_write_stdout(const void *buf, int siz)
 {
 {
     return write(fileno_stdout(), buf, siz);
     return write(fileno_stdout(), buf, siz);

+ 101 - 19
libs/openssl/apps/lib/cmp_mock_srv.c

@@ -27,7 +27,7 @@ typedef struct
     X509 *oldWithNew;          /* to return in oldWithNew of rootKeyUpdate */
     X509 *oldWithNew;          /* to return in oldWithNew of rootKeyUpdate */
     OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */
     OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */
     int sendError;             /* send error response on given request type */
     int sendError;             /* send error response on given request type */
-    OSSL_CMP_MSG *certReq;     /* ir/cr/p10cr/kur remembered while polling */
+    OSSL_CMP_MSG *req;         /* original request message during polling */
     int pollCount;             /* number of polls before actual cert response */
     int pollCount;             /* number of polls before actual cert response */
     int curr_pollCount;        /* number of polls so far for current request */
     int curr_pollCount;        /* number of polls so far for current request */
     int checkAfterTime;        /* time the client should wait between polling */
     int checkAfterTime;        /* time the client should wait between polling */
@@ -43,7 +43,7 @@ static void mock_srv_ctx_free(mock_srv_ctx *ctx)
     X509_free(ctx->certOut);
     X509_free(ctx->certOut);
     OSSL_STACK_OF_X509_free(ctx->chainOut);
     OSSL_STACK_OF_X509_free(ctx->chainOut);
     OSSL_STACK_OF_X509_free(ctx->caPubsOut);
     OSSL_STACK_OF_X509_free(ctx->caPubsOut);
-    OSSL_CMP_MSG_free(ctx->certReq);
+    OSSL_CMP_MSG_free(ctx->req);
     OPENSSL_free(ctx);
     OPENSSL_free(ctx);
 }
 }
 
 
@@ -183,6 +183,38 @@ int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec)
     return 1;
     return 1;
 }
 }
 
 
+/* determine whether to delay response to (non-polling) request */
+static int delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req)
+{
+    mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+    int req_type = OSSL_CMP_MSG_get_bodytype(req);
+
+    if (ctx == NULL || req == NULL) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+        return -1;
+    }
+
+    /*
+     * For ir/cr/p10cr/kur delayed delivery is handled separately in
+     * process_cert_request
+     */
+    if (req_type == OSSL_CMP_IR
+        || req_type == OSSL_CMP_CR
+        || req_type == OSSL_CMP_P10CR
+        || req_type == OSSL_CMP_KUR
+        /* Client may use error to abort the ongoing polling */
+        || req_type == OSSL_CMP_ERROR)
+        return 0;
+
+    if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) {
+        /* start polling */
+        if ((ctx->req = OSSL_CMP_MSG_dup(req)) == NULL)
+            return -1;
+        return 1;
+    }
+    return 0;
+}
+
 /* check for matching reference cert components, as far as given */
 /* check for matching reference cert components, as far as given */
 static int refcert_cmp(const X509 *refcert,
 static int refcert_cmp(const X509 *refcert,
                        const X509_NAME *issuer, const ASN1_INTEGER *serial)
                        const X509_NAME *issuer, const ASN1_INTEGER *serial)
@@ -198,6 +230,23 @@ static int refcert_cmp(const X509 *refcert,
         && (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0);
         && (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0);
 }
 }
 
 
+/* reset the state that belongs to a transaction */
+static int clean_transaction(OSSL_CMP_SRV_CTX *srv_ctx,
+                             ossl_unused const ASN1_OCTET_STRING *id)
+{
+    mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+        return 0;
+    }
+
+    ctx->curr_pollCount = 0;
+    OSSL_CMP_MSG_free(ctx->req);
+    ctx->req = NULL;
+    return 1;
+}
+
 static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
 static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
                                             const OSSL_CMP_MSG *cert_req,
                                             const OSSL_CMP_MSG *cert_req,
                                             ossl_unused int certReqId,
                                             ossl_unused int certReqId,
@@ -228,12 +277,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
 
 
     if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) {
     if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) {
         /* start polling */
         /* start polling */
-        if (ctx->certReq != NULL) {
-            /* already in polling mode */
-            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
-            return NULL;
-        }
-        if ((ctx->certReq = OSSL_CMP_MSG_dup(cert_req)) == NULL)
+        if ((ctx->req = OSSL_CMP_MSG_dup(cert_req)) == NULL)
             return NULL;
             return NULL;
         return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL);
         return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL);
     }
     }
@@ -241,6 +285,42 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
         /* give final response after polling */
         /* give final response after polling */
         ctx->curr_pollCount = 0;
         ctx->curr_pollCount = 0;
 
 
+    /* accept cert profile for cr messages only with the configured name */
+    if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_CR) {
+        STACK_OF(OSSL_CMP_ITAV) *itavs =
+            OSSL_CMP_HDR_get0_geninfo_ITAVs(OSSL_CMP_MSG_get0_header(cert_req));
+        int i;
+
+        for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) {
+            OSSL_CMP_ITAV *itav = sk_OSSL_CMP_ITAV_value(itavs, i);
+            ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(itav);
+            STACK_OF(ASN1_UTF8STRING) *strs;
+            ASN1_UTF8STRING *str;
+            const char *data;
+
+            if (OBJ_obj2nid(obj) == NID_id_it_certProfile) {
+                if (!OSSL_CMP_ITAV_get0_certProfile(itav, &strs))
+                    return NULL;
+                if (sk_ASN1_UTF8STRING_num(strs) < 1) {
+                    ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE);
+                    return NULL;
+                }
+                str = sk_ASN1_UTF8STRING_value(strs, 0);
+                if (str == NULL
+                    || (data =
+                        (const char *)ASN1_STRING_get0_data(str)) == NULL) {
+                    ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
+                    return NULL;
+                }
+                if (strcmp(data, "profile1") != 0) {
+                    ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE);
+                    return NULL;
+                }
+                break;
+            }
+        }
+    }
+
     /* accept cert update request only for the reference cert, if given */
     /* accept cert update request only for the reference cert, if given */
     if (bodytype == OSSL_CMP_KUR
     if (bodytype == OSSL_CMP_KUR
             && crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) {
             && crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) {
@@ -455,38 +535,38 @@ static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
     return 1;
     return 1;
 }
 }
 
 
+/* return 0 on failure, 1 on success, setting *req or otherwise *check_after */
 static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
 static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
                            const OSSL_CMP_MSG *pollReq,
                            const OSSL_CMP_MSG *pollReq,
                            ossl_unused int certReqId,
                            ossl_unused int certReqId,
-                           OSSL_CMP_MSG **certReq, int64_t *check_after)
+                           OSSL_CMP_MSG **req, int64_t *check_after)
 {
 {
     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
 
 
+    if (req != NULL)
+        *req = NULL;
     if (ctx == NULL || pollReq == NULL
     if (ctx == NULL || pollReq == NULL
-            || certReq == NULL || check_after == NULL) {
+            || req == NULL || check_after == NULL) {
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return 0;
         return 0;
     }
     }
+
     if (ctx->sendError == 1
     if (ctx->sendError == 1
             || ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) {
             || ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) {
-        *certReq = NULL;
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return 0;
         return 0;
     }
     }
-    if (ctx->certReq == NULL) {
-        /* not currently in polling mode */
-        *certReq = NULL;
-        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
+    if (ctx->req == NULL) { /* not currently in polling mode */
+        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_POLLREQ);
         return 0;
         return 0;
     }
     }
 
 
     if (++ctx->curr_pollCount >= ctx->pollCount) {
     if (++ctx->curr_pollCount >= ctx->pollCount) {
         /* end polling */
         /* end polling */
-        *certReq = ctx->certReq;
-        ctx->certReq = NULL;
+        *req = ctx->req;
+        ctx->req = NULL;
         *check_after = 0;
         *check_after = 0;
     } else {
     } else {
-        *certReq = NULL;
         *check_after = ctx->checkAfterTime;
         *check_after = ctx->checkAfterTime;
     }
     }
     return 1;
     return 1;
@@ -500,7 +580,9 @@ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq)
     if (srv_ctx != NULL && ctx != NULL
     if (srv_ctx != NULL && ctx != NULL
             && OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request,
             && OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request,
                                      process_rr, process_genm, process_error,
                                      process_rr, process_genm, process_error,
-                                     process_certConf, process_pollReq))
+                                     process_certConf, process_pollReq)
+            && OSSL_CMP_SRV_CTX_init_trans(srv_ctx,
+                                           delayed_delivery, clean_transaction))
         return srv_ctx;
         return srv_ctx;
 
 
     mock_srv_ctx_free(ctx);
     mock_srv_ctx_free(ctx);

+ 2 - 8
libs/openssl/apps/lib/http_server.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -26,12 +26,6 @@
 #include "s_apps.h"
 #include "s_apps.h"
 #include "log.h"
 #include "log.h"
 
 
-#if defined(__TANDEM)
-# if defined(OPENSSL_TANDEM_FLOSS)
-#  include <floss.h(floss_fork)>
-# endif
-#endif
-
 #define HTTP_PREFIX "HTTP/"
 #define HTTP_PREFIX "HTTP/"
 #define HTTP_VERSION_PATT "1." /* allow 1.x */
 #define HTTP_VERSION_PATT "1." /* allow 1.x */
 #define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT
 #define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT
@@ -200,7 +194,7 @@ BIO *http_server_init(const char *prog, const char *port, int verb)
     int port_num;
     int port_num;
     char name[40];
     char name[40];
 
 
-    snprintf(name, sizeof(name), "*:%s", port); /* port may be "0" */
+    BIO_snprintf(name, sizeof(name), "*:%s", port); /* port may be "0" */
     if (verb >= 0 && !log_set_verbosity(prog, verb))
     if (verb >= 0 && !log_set_verbosity(prog, verb))
         return NULL;
         return NULL;
     bufbio = BIO_new(BIO_f_buffer());
     bufbio = BIO_new(BIO_f_buffer());

+ 1 - 7
libs/openssl/apps/lib/s_socket.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -41,12 +41,6 @@ typedef unsigned int u_int;
 # include "s_apps.h"
 # include "s_apps.h"
 # include "internal/sockets.h"
 # include "internal/sockets.h"
 
 
-# if defined(__TANDEM)
-#  if defined(OPENSSL_TANDEM_FLOSS)
-#   include <floss.h(floss_read)>
-#  endif
-# endif
-
 # include <openssl/bio.h>
 # include <openssl/bio.h>
 # include <openssl/err.h>
 # include <openssl/err.h>
 
 

+ 1 - 7
libs/openssl/apps/ocsp.c

@@ -11,7 +11,7 @@
 
 
 #ifdef OPENSSL_SYS_VMS
 #ifdef OPENSSL_SYS_VMS
   /* So fd_set and friends get properly defined on OpenVMS */
   /* So fd_set and friends get properly defined on OpenVMS */
-# define _XOPEN_SOURCE_EXTENDED 1
+# define _XOPEN_SOURCE_EXTENDED
 #endif
 #endif
 
 
 #include <stdio.h>
 #include <stdio.h>
@@ -33,12 +33,6 @@
 #include <openssl/bn.h>
 #include <openssl/bn.h>
 #include <openssl/x509v3.h>
 #include <openssl/x509v3.h>
 
 
-#if defined(__TANDEM)
-# if defined(OPENSSL_TANDEM_FLOSS)
-#  include <floss.h(floss_fork)>
-# endif
-#endif
-
 #if defined(OPENSSL_SYS_VXWORKS)
 #if defined(OPENSSL_SYS_VXWORKS)
 /* not supported */
 /* not supported */
 int setpgid(pid_t pid, pid_t pgid)
 int setpgid(pid_t pid, pid_t pgid)

+ 86 - 7
libs/openssl/apps/rand.c

@@ -25,7 +25,7 @@ typedef enum OPTION_choice {
 } OPTION_CHOICE;
 } OPTION_CHOICE;
 
 
 const OPTIONS rand_options[] = {
 const OPTIONS rand_options[] = {
-    {OPT_HELP_STR, 1, '-', "Usage: %s [options] num\n"},
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] num[K|M|G|T]\n"},
 
 
     OPT_SECTION("General"),
     OPT_SECTION("General"),
     {"help", OPT_HELP, '-', "Display this summary"},
     {"help", OPT_HELP, '-', "Display this summary"},
@@ -52,8 +52,10 @@ int rand_main(int argc, char **argv)
     BIO *out = NULL;
     BIO *out = NULL;
     char *outfile = NULL, *prog;
     char *outfile = NULL, *prog;
     OPTION_CHOICE o;
     OPTION_CHOICE o;
-    int format = FORMAT_BINARY, r, i, ret = 1, buflen = 131072;
+    int format = FORMAT_BINARY, r, i, ret = 1;
+    size_t buflen = (1 << 16); /* max rand chunk size is 2^16 bytes */
     long num = -1;
     long num = -1;
+    uint64_t scaled_num = 0;
     uint8_t *buf = NULL;
     uint8_t *buf = NULL;
 
 
     prog = opt_init(argc, argv, rand_options);
     prog = opt_init(argc, argv, rand_options);
@@ -95,8 +97,85 @@ int rand_main(int argc, char **argv)
     argc = opt_num_rest();
     argc = opt_num_rest();
     argv = opt_rest();
     argv = opt_rest();
     if (argc == 1) {
     if (argc == 1) {
-        if (!opt_long(argv[0], &num) || num <= 0)
+        int factoridx = 0;
+        int shift = 0;
+
+        /*
+         * special case for requesting the max allowed
+         * number of random bytes to be generated
+         */
+        if (!strcmp(argv[0], "max")) {
+            /*
+             * 2^61 bytes is the limit of random output
+             * per drbg instantiation
+             */
+            scaled_num = UINT64_MAX >> 3;
+        } else {
+            /*
+             * iterate over the value and check to see if there are
+             * any non-numerical chars
+             * A non digit suffix indicates we need to shift the
+             * number of requested bytes by a factor of:
+             * K = 1024^1 (1 << (10 * 1))
+             * M = 1024^2 (1 << (10 * 2))
+             * G = 1024^3 (1 << (10 * 3))
+             * T = 1024^4 (1 << (10 * 4))
+             * which can be achieved by bit-shifting the number
+             */
+            while (argv[0][factoridx]) {
+                if (!isdigit((int)(argv[0][factoridx]))) {
+                    switch(argv[0][factoridx]) {
+                    case 'K':
+                        shift = 10;
+                        break;
+                    case 'M':
+                        shift = 20;
+                        break;
+                    case 'G':
+                        shift = 30;
+                        break;
+                    case 'T':
+                        shift = 40;
+                        break;
+                    default:
+                        BIO_printf(bio_err, "Invalid size suffix %s\n",
+                                   &argv[0][factoridx]);
+                        goto opthelp;
+                    }
+                    break;
+                }
+                factoridx++;
+            }
+
+            if (shift != 0 && strlen(&argv[0][factoridx]) != 1) {
+                BIO_printf(bio_err, "Invalid size suffix %s\n",
+                           &argv[0][factoridx]);
+                goto opthelp;
+            }
+        }
+        /* Remove the suffix from the arg so that opt_long works */
+        if (shift != 0)
+            argv[0][factoridx] = '\0';
+
+        if ((scaled_num == 0) && (!opt_long(argv[0], &num) || num <= 0))
             goto opthelp;
             goto opthelp;
+
+        if (shift != 0) {
+            /* check for overflow */
+            if ((UINT64_MAX >> shift) < (size_t)num) {
+                BIO_printf(bio_err, "%lu bytes with suffix overflows\n",
+                           num);
+                goto opthelp;
+            }
+            scaled_num = num << shift;
+            if (scaled_num > (UINT64_MAX >> 3)) {
+                BIO_printf(bio_err, "Request exceeds max allowed output\n");
+                goto opthelp;
+            }
+        } else {
+            if (scaled_num == 0)
+                scaled_num = num;
+        }
     } else if (!opt_check_rest_arg(NULL)) {
     } else if (!opt_check_rest_arg(NULL)) {
         goto opthelp;
         goto opthelp;
     }
     }
@@ -116,10 +195,10 @@ int rand_main(int argc, char **argv)
     }
     }
 
 
     buf = app_malloc(buflen, "buffer for output file");
     buf = app_malloc(buflen, "buffer for output file");
-    while (num > 0) {
-        long chunk;
+    while (scaled_num > 0) {
+        int chunk;
 
 
-        chunk = (num > buflen) ? buflen : num;
+        chunk = scaled_num > buflen ? (int)buflen : (int)scaled_num;
         r = RAND_bytes(buf, chunk);
         r = RAND_bytes(buf, chunk);
         if (r <= 0)
         if (r <= 0)
             goto end;
             goto end;
@@ -131,7 +210,7 @@ int rand_main(int argc, char **argv)
                 if (BIO_printf(out, "%02x", buf[i]) != 2)
                 if (BIO_printf(out, "%02x", buf[i]) != 2)
                     goto end;
                     goto end;
         }
         }
-        num -= chunk;
+        scaled_num -= chunk;
     }
     }
     if (format == FORMAT_TEXT)
     if (format == FORMAT_TEXT)
         BIO_puts(out, "\n");
         BIO_puts(out, "\n");

+ 2 - 2
libs/openssl/apps/rehash.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2013-2014 Timo Teräs <[email protected]>
  * Copyright (c) 2013-2014 Timo Teräs <[email protected]>
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -266,7 +266,7 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h)
 
 
     if (sk_X509_INFO_num(inf) != 1) {
     if (sk_X509_INFO_num(inf) != 1) {
         BIO_printf(bio_err,
         BIO_printf(bio_err,
-                   "%s: warning: skipping %s,"
+                   "%s: warning: skipping %s, "
                    "it does not contain exactly one certificate or CRL\n",
                    "it does not contain exactly one certificate or CRL\n",
                    opt_getprog(), filename);
                    opt_getprog(), filename);
         /* This is not an error. */
         /* This is not an error. */

+ 3 - 2
libs/openssl/apps/req.c

@@ -918,9 +918,10 @@ int req_main(int argc, char **argv)
 
 
         if (i < 0)
         if (i < 0)
             goto end;
             goto end;
-        if (i == 0)
+        if (i == 0) {
             BIO_printf(bio_err, "Certificate request self-signature verify failure\n");
             BIO_printf(bio_err, "Certificate request self-signature verify failure\n");
-        else /* i > 0 */
+	    goto end;
+        } else /* i > 0 */
             BIO_printf(bio_out, "Certificate request self-signature verify OK\n");
             BIO_printf(bio_out, "Certificate request self-signature verify OK\n");
     }
     }
 
 

+ 30 - 14
libs/openssl/apps/s_server.c

@@ -476,7 +476,10 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx,
     char *proxy = NULL, *no_proxy = NULL;
     char *proxy = NULL, *no_proxy = NULL;
     int use_ssl;
     int use_ssl;
     STACK_OF(OPENSSL_STRING) *aia = NULL;
     STACK_OF(OPENSSL_STRING) *aia = NULL;
-    X509 *x = NULL;
+    X509 *x = NULL, *cert;
+    X509_NAME *iname;
+    STACK_OF(X509) *chain = NULL;
+    SSL_CTX *ssl_ctx;
     X509_STORE_CTX *inctx = NULL;
     X509_STORE_CTX *inctx = NULL;
     X509_OBJECT *obj;
     X509_OBJECT *obj;
     OCSP_REQUEST *req = NULL;
     OCSP_REQUEST *req = NULL;
@@ -487,6 +490,7 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx,
 
 
     /* Build up OCSP query from server certificate */
     /* Build up OCSP query from server certificate */
     x = SSL_get_certificate(s);
     x = SSL_get_certificate(s);
+    iname = X509_get_issuer_name(x);
     aia = X509_get1_ocsp(x);
     aia = X509_get1_ocsp(x);
     if (aia != NULL) {
     if (aia != NULL) {
         if (!OSSL_HTTP_parse_url(sk_OPENSSL_STRING_value(aia, 0), &use_ssl,
         if (!OSSL_HTTP_parse_url(sk_OPENSSL_STRING_value(aia, 0), &use_ssl,
@@ -511,21 +515,33 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx,
     proxy = srctx->proxy;
     proxy = srctx->proxy;
     no_proxy = srctx->no_proxy;
     no_proxy = srctx->no_proxy;
 
 
-    inctx = X509_STORE_CTX_new();
-    if (inctx == NULL)
+    ssl_ctx = SSL_get_SSL_CTX(s);
+    if (!SSL_CTX_get0_chain_certs(ssl_ctx, &chain))
         goto err;
         goto err;
-    if (!X509_STORE_CTX_init(inctx,
-                             SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
-                             NULL, NULL))
-        goto err;
-    obj = X509_STORE_CTX_get_obj_by_subject(inctx, X509_LU_X509,
-                                            X509_get_issuer_name(x));
-    if (obj == NULL) {
-        BIO_puts(bio_err, "cert_status: Can't retrieve issuer certificate.\n");
-        goto done;
+    for (i = 0; i < sk_X509_num(chain); i++) {
+        /* check the untrusted certificate chain (-cert_chain option) */
+        cert = sk_X509_value(chain, i);
+        if (X509_name_cmp(iname, X509_get_subject_name(cert)) == 0) {
+            /* the issuer certificate is found */
+            id = OCSP_cert_to_id(NULL, x, cert);
+            break;
+        }
+    }
+    if (id == NULL) {
+        inctx = X509_STORE_CTX_new();
+        if (inctx == NULL)
+            goto err;
+        if (!X509_STORE_CTX_init(inctx, SSL_CTX_get_cert_store(ssl_ctx),
+                                 NULL, NULL))
+            goto err;
+        obj = X509_STORE_CTX_get_obj_by_subject(inctx, X509_LU_X509, iname);
+        if (obj == NULL) {
+            BIO_puts(bio_err, "cert_status: Can't retrieve issuer certificate.\n");
+            goto done;
+        }
+        id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj));
+        X509_OBJECT_free(obj);
     }
     }
-    id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj));
-    X509_OBJECT_free(obj);
     if (id == NULL)
     if (id == NULL)
         goto err;
         goto err;
     req = OCSP_REQUEST_new();
     req = OCSP_REQUEST_new();

+ 2 - 3
libs/openssl/apps/s_time.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -310,7 +310,6 @@ int s_time_main(int argc, char **argv)
     }
     }
     totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
     totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
 
 
-    i = (int)((long)time(NULL) - finishtime + maxtime);
     printf
     printf
         ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
         ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
          nConn, totalTime, ((double)nConn / totalTime), bytes_read);
          nConn, totalTime, ((double)nConn / totalTime), bytes_read);
@@ -338,7 +337,7 @@ int s_time_main(int argc, char **argv)
         buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path);
         buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path);
         if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0)
         if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0)
             goto end;
             goto end;
-        while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
+        while (SSL_read(scon, buf, sizeof(buf)) > 0)
             continue;
             continue;
     }
     }
     SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
     SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);

+ 120 - 58
libs/openssl/apps/speed.c

@@ -47,12 +47,6 @@
 # include <unistd.h>
 # include <unistd.h>
 #endif
 #endif
 
 
-#if defined(__TANDEM)
-# if defined(OPENSSL_TANDEM_FLOSS)
-#  include <floss.h(floss_fork)>
-# endif
-#endif
-
 #if defined(_WIN32)
 #if defined(_WIN32)
 # include <windows.h>
 # include <windows.h>
 /*
 /*
@@ -305,17 +299,18 @@ enum {
     D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST,
     D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST,
     D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES,
     D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES,
     D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML,
     D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML,
-    D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM
+    D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, D_KMAC128, D_KMAC256,
+    ALGOR_NUM
 };
 };
 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
 static const char *names[ALGOR_NUM] = {
 static const char *names[ALGOR_NUM] = {
     "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
     "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
-    "sha256", "sha512", "whirlpool", "hmac(md5)",
+    "sha256", "sha512", "whirlpool", "hmac(sha256)",
     "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
     "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
     "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
     "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
     "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
     "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
     "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
     "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
-    "evp", "ghash", "rand", "cmac"
+    "evp", "ghash", "rand", "cmac", "kmac128", "kmac256"
 };
 };
 
 
 /* list of configured algorithm (remaining), with some few alias */
 /* list of configured algorithm (remaining), with some few alias */
@@ -356,7 +351,9 @@ static const OPT_PAIR doit_choices[] = {
     {"cast", D_CBC_CAST},
     {"cast", D_CBC_CAST},
     {"cast5", D_CBC_CAST},
     {"cast5", D_CBC_CAST},
     {"ghash", D_GHASH},
     {"ghash", D_GHASH},
-    {"rand", D_RAND}
+    {"rand", D_RAND},
+    {"kmac128", D_KMAC128},
+    {"kmac256", D_KMAC256},
 };
 };
 
 
 static double results[ALGOR_NUM][SIZE_NUM];
 static double results[ALGOR_NUM][SIZE_NUM];
@@ -570,7 +567,7 @@ static int run_benchmark(int async_jobs, int (*loop_function) (void *),
 
 
 static unsigned int testnum;
 static unsigned int testnum;
 
 
-static char *evp_mac_mdname = "md5";
+static char *evp_mac_mdname = "sha256";
 static char *evp_hmac_name = NULL;
 static char *evp_hmac_name = NULL;
 static const char *evp_md_name = NULL;
 static const char *evp_md_name = NULL;
 static char *evp_mac_ciphername = "aes-128-cbc";
 static char *evp_mac_ciphername = "aes-128-cbc";
@@ -655,6 +652,41 @@ static int MD5_loop(void *args)
     return EVP_Digest_loop("md5", D_MD5, args);
     return EVP_Digest_loop("md5", D_MD5, args);
 }
 }
 
 
+static int mac_setup(const char *name,
+                     EVP_MAC **mac, OSSL_PARAM params[],
+                     loopargs_t *loopargs, unsigned int loopargs_len)
+{
+    unsigned int i;
+
+    *mac = EVP_MAC_fetch(app_get0_libctx(), name, app_get0_propq());
+    if (*mac == NULL)
+        return 0;
+
+    for (i = 0; i < loopargs_len; i++) {
+        loopargs[i].mctx = EVP_MAC_CTX_new(*mac);
+        if (loopargs[i].mctx == NULL)
+            return 0;
+
+        if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
+            return 0;
+    }
+
+    return 1;
+}
+
+static void mac_teardown(EVP_MAC **mac,
+                         loopargs_t *loopargs, unsigned int loopargs_len)
+{
+    unsigned int i;
+
+    for (i = 0; i < loopargs_len; i++)
+        EVP_MAC_CTX_free(loopargs[i].mctx);
+    EVP_MAC_free(*mac);
+    *mac = NULL;
+
+    return;
+}
+
 static int EVP_MAC_loop(ossl_unused int algindex, void *args)
 static int EVP_MAC_loop(ossl_unused int algindex, void *args)
 {
 {
     loopargs_t *tempargs = *(loopargs_t **) args;
     loopargs_t *tempargs = *(loopargs_t **) args;
@@ -684,6 +716,16 @@ static int CMAC_loop(void *args)
     return EVP_MAC_loop(D_EVP_CMAC, args);
     return EVP_MAC_loop(D_EVP_CMAC, args);
 }
 }
 
 
+static int KMAC128_loop(void *args)
+{
+    return EVP_MAC_loop(D_KMAC128, args);
+}
+
+static int KMAC256_loop(void *args)
+{
+    return EVP_MAC_loop(D_KMAC256, args);
+}
+
 static int SHA1_loop(void *args)
 static int SHA1_loop(void *args)
 {
 {
     return EVP_Digest_loop("sha1", D_SHA1, args);
     return EVP_Digest_loop("sha1", D_SHA1, args);
@@ -2226,6 +2268,14 @@ int speed_main(int argc, char **argv)
             do_sigs = 1;
             do_sigs = 1;
             algo_found = 1;
             algo_found = 1;
         }
         }
+        if (strcmp(algo, "kmac") == 0) {
+            doit[D_KMAC128] = doit[D_KMAC256] = 1;
+            algo_found = 1;
+        }
+        if (strcmp(algo, "cmac") == 0) {
+            doit[D_EVP_CMAC] = 1;
+            algo_found = 1;
+        }
 
 
         if (!algo_found) {
         if (!algo_found) {
             BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
             BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
@@ -2525,10 +2575,8 @@ int speed_main(int argc, char **argv)
         int len = strlen(hmac_key);
         int len = strlen(hmac_key);
         OSSL_PARAM params[3];
         OSSL_PARAM params[3];
 
 
-        mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
-        if (mac == NULL || evp_mac_mdname == NULL)
+        if (evp_mac_mdname == NULL)
             goto end;
             goto end;
-
         evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
         evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
                                    "HMAC name");
                                    "HMAC name");
         sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
         sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
@@ -2542,14 +2590,8 @@ int speed_main(int argc, char **argv)
                                               (char *)hmac_key, len);
                                               (char *)hmac_key, len);
         params[2] = OSSL_PARAM_construct_end();
         params[2] = OSSL_PARAM_construct_end();
 
 
-        for (i = 0; i < loopargs_len; i++) {
-            loopargs[i].mctx = EVP_MAC_CTX_new(mac);
-            if (loopargs[i].mctx == NULL)
-                goto end;
-
-            if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
-                goto skip_hmac; /* Digest not found */
-        }
+        if (mac_setup("HMAC", &mac, params, loopargs, loopargs_len) < 1)
+            goto end;
         for (testnum = 0; testnum < size_num; testnum++) {
         for (testnum = 0; testnum < size_num; testnum++) {
             print_message(names[D_HMAC], lengths[testnum], seconds.sym);
             print_message(names[D_HMAC], lengths[testnum], seconds.sym);
             Time_F(START);
             Time_F(START);
@@ -2559,12 +2601,9 @@ int speed_main(int argc, char **argv)
             if (count < 0)
             if (count < 0)
                 break;
                 break;
         }
         }
-        for (i = 0; i < loopargs_len; i++)
-            EVP_MAC_CTX_free(loopargs[i].mctx);
-        EVP_MAC_free(mac);
-        mac = NULL;
+        mac_teardown(&mac, loopargs, loopargs_len);
     }
     }
-skip_hmac:
+
     if (doit[D_CBC_DES]) {
     if (doit[D_CBC_DES]) {
         int st = 1;
         int st = 1;
 
 
@@ -2681,25 +2720,22 @@ skip_hmac:
     }
     }
     if (doit[D_GHASH]) {
     if (doit[D_GHASH]) {
         static const char gmac_iv[] = "0123456789ab";
         static const char gmac_iv[] = "0123456789ab";
-        OSSL_PARAM params[3];
-
-        mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
-        if (mac == NULL)
-            goto end;
+        OSSL_PARAM params[4];
 
 
         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
                                                      "aes-128-gcm", 0);
                                                      "aes-128-gcm", 0);
         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
                                                       (char *)gmac_iv,
                                                       (char *)gmac_iv,
                                                       sizeof(gmac_iv) - 1);
                                                       sizeof(gmac_iv) - 1);
-        params[2] = OSSL_PARAM_construct_end();
+        params[2] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                      (void *)key32, 16);
+        params[3] = OSSL_PARAM_construct_end();
 
 
+        if (mac_setup("GMAC", &mac, params, loopargs, loopargs_len) < 1)
+            goto end;
+        /* b/c of the definition of GHASH_loop(), init() calls are needed here */
         for (i = 0; i < loopargs_len; i++) {
         for (i = 0; i < loopargs_len; i++) {
-            loopargs[i].mctx = EVP_MAC_CTX_new(mac);
-            if (loopargs[i].mctx == NULL)
-                goto end;
-
-            if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params))
+            if (!EVP_MAC_init(loopargs[i].mctx, NULL, 0, NULL))
                 goto end;
                 goto end;
         }
         }
         for (testnum = 0; testnum < size_num; testnum++) {
         for (testnum = 0; testnum < size_num; testnum++) {
@@ -2711,10 +2747,7 @@ skip_hmac:
             if (count < 0)
             if (count < 0)
                 break;
                 break;
         }
         }
-        for (i = 0; i < loopargs_len; i++)
-            EVP_MAC_CTX_free(loopargs[i].mctx);
-        EVP_MAC_free(mac);
-        mac = NULL;
+        mac_teardown(&mac, loopargs, loopargs_len);
     }
     }
 
 
     if (doit[D_RAND]) {
     if (doit[D_RAND]) {
@@ -2813,9 +2846,6 @@ skip_hmac:
         OSSL_PARAM params[3];
         OSSL_PARAM params[3];
         EVP_CIPHER *cipher = NULL;
         EVP_CIPHER *cipher = NULL;
 
 
-        mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
-        if (mac == NULL || evp_mac_ciphername == NULL)
-            goto end;
         if (!opt_cipher(evp_mac_ciphername, &cipher))
         if (!opt_cipher(evp_mac_ciphername, &cipher))
             goto end;
             goto end;
 
 
@@ -2836,15 +2866,8 @@ skip_hmac:
                                                       (char *)key32, keylen);
                                                       (char *)key32, keylen);
         params[2] = OSSL_PARAM_construct_end();
         params[2] = OSSL_PARAM_construct_end();
 
 
-        for (i = 0; i < loopargs_len; i++) {
-            loopargs[i].mctx = EVP_MAC_CTX_new(mac);
-            if (loopargs[i].mctx == NULL)
-                goto end;
-
-            if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
-                goto end;
-        }
-
+        if (mac_setup("CMAC", &mac, params, loopargs, loopargs_len) < 1)
+            goto end;
         for (testnum = 0; testnum < size_num; testnum++) {
         for (testnum = 0; testnum < size_num; testnum++) {
             print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym);
             print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym);
             Time_F(START);
             Time_F(START);
@@ -2854,10 +2877,49 @@ skip_hmac:
             if (count < 0)
             if (count < 0)
                 break;
                 break;
         }
         }
-        for (i = 0; i < loopargs_len; i++)
-            EVP_MAC_CTX_free(loopargs[i].mctx);
-        EVP_MAC_free(mac);
-        mac = NULL;
+        mac_teardown(&mac, loopargs, loopargs_len);
+    }
+
+    if (doit[D_KMAC128]) {
+        OSSL_PARAM params[2];
+
+        params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                      (void *)key32, 16);
+        params[1] = OSSL_PARAM_construct_end();
+
+        if (mac_setup("KMAC-128", &mac, params, loopargs, loopargs_len) < 1)
+            goto end;
+        for (testnum = 0; testnum < size_num; testnum++) {
+            print_message(names[D_KMAC128], lengths[testnum], seconds.sym);
+            Time_F(START);
+            count = run_benchmark(async_jobs, KMAC128_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_KMAC128, testnum, count, d);
+            if (count < 0)
+                break;
+        }
+        mac_teardown(&mac, loopargs, loopargs_len);
+    }
+
+    if (doit[D_KMAC256]) {
+        OSSL_PARAM params[2];
+
+        params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                      (void *)key32, 32);
+        params[1] = OSSL_PARAM_construct_end();
+
+        if (mac_setup("KMAC-256", &mac, params, loopargs, loopargs_len) < 1)
+            goto end;
+        for (testnum = 0; testnum < size_num; testnum++) {
+            print_message(names[D_KMAC256], lengths[testnum], seconds.sym);
+            Time_F(START);
+            count = run_benchmark(async_jobs, KMAC256_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_KMAC256, testnum, count, d);
+            if (count < 0)
+                break;
+        }
+        mac_teardown(&mac, loopargs, loopargs_len);
     }
     }
 
 
     for (i = 0; i < loopargs_len; i++)
     for (i = 0; i < loopargs_len; i++)

+ 20 - 6
libs/openssl/apps/x509.c

@@ -44,7 +44,7 @@ typedef enum OPTION_choice {
     OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM,
     OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM,
     OPT_CAKEYFORM, OPT_VFYOPT, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE,
     OPT_CAKEYFORM, OPT_VFYOPT, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE,
     OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_KEY, OPT_SIGNKEY, OPT_CA, OPT_CAKEY,
     OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_KEY, OPT_SIGNKEY, OPT_CA, OPT_CAKEY,
-    OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_SUBJ,
+    OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_ISSU, OPT_SUBJ,
     OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_DATEOPT, OPT_NAMEOPT,
     OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_DATEOPT, OPT_NAMEOPT,
     OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL,
     OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL,
     OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH,
     OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH,
@@ -139,7 +139,9 @@ const OPTIONS x509_options[] = {
      "Number of days until newly generated certificate expires - default 30"},
      "Number of days until newly generated certificate expires - default 30"},
     {"preserve_dates", OPT_PRESERVE_DATES, '-',
     {"preserve_dates", OPT_PRESERVE_DATES, '-',
      "Preserve existing validity dates"},
      "Preserve existing validity dates"},
-    {"subj", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"},
+    {"set_issuer", OPT_ISSU, 's', "Set or override certificate issuer"},
+    {"set_subject", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"},
+    {"subj", OPT_SUBJ, 's', "Alias for -set_subject"},
     {"force_pubkey", OPT_FORCE_PUBKEY, '<',
     {"force_pubkey", OPT_FORCE_PUBKEY, '<',
      "Key to be placed in new certificate or certificate request"},
      "Key to be placed in new certificate or certificate request"},
     {"clrext", OPT_CLREXT, '-',
     {"clrext", OPT_CLREXT, '-',
@@ -263,8 +265,8 @@ int x509_main(int argc, char **argv)
     EVP_PKEY *privkey = NULL, *CAkey = NULL, *pubkey = NULL;
     EVP_PKEY *privkey = NULL, *CAkey = NULL, *pubkey = NULL;
     EVP_PKEY *pkey;
     EVP_PKEY *pkey;
     int newcert = 0;
     int newcert = 0;
-    char *subj = NULL, *digest = NULL;
-    X509_NAME *fsubj = NULL;
+    char *issu = NULL, *subj = NULL, *digest = NULL;
+    X509_NAME *fissu = NULL, *fsubj = NULL;
     const unsigned long chtype = MBSTRING_ASC;
     const unsigned long chtype = MBSTRING_ASC;
     const int multirdn = 1;
     const int multirdn = 1;
     STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
     STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
@@ -426,6 +428,9 @@ int x509_main(int argc, char **argv)
         case OPT_FORCE_PUBKEY:
         case OPT_FORCE_PUBKEY:
             pubkeyfile = opt_arg();
             pubkeyfile = opt_arg();
             break;
             break;
+        case OPT_ISSU:
+            issu = opt_arg();
+            break;
         case OPT_SUBJ:
         case OPT_SUBJ:
             subj = opt_arg();
             subj = opt_arg();
             break;
             break;
@@ -652,6 +657,9 @@ int x509_main(int argc, char **argv)
             goto err;
             goto err;
         }
         }
     }
     }
+    if (issu != NULL
+            && (fissu = parse_name(issu, chtype, multirdn, "issuer")) == NULL)
+        goto end;
     if (subj != NULL
     if (subj != NULL
             && (fsubj = parse_name(subj, chtype, multirdn, "subject")) == NULL)
             && (fsubj = parse_name(subj, chtype, multirdn, "subject")) == NULL)
         goto end;
         goto end;
@@ -831,8 +839,13 @@ int x509_main(int argc, char **argv)
     if (reqfile || newcert || privkey != NULL || CAfile != NULL) {
     if (reqfile || newcert || privkey != NULL || CAfile != NULL) {
         if (!preserve_dates && !set_cert_times(x, NULL, NULL, days))
         if (!preserve_dates && !set_cert_times(x, NULL, NULL, days))
             goto end;
             goto end;
-        if (!X509_set_issuer_name(x, X509_get_subject_name(issuer_cert)))
-            goto end;
+        if (fissu != NULL) {
+            if (!X509_set_issuer_name(x, fissu))
+                goto end;
+        } else {
+            if (!X509_set_issuer_name(x, X509_get_subject_name(issuer_cert)))
+                goto end;
+        }
     }
     }
 
 
     X509V3_set_ctx(&ext_ctx, issuer_cert, x, NULL, NULL, X509V3_CTX_REPLACE);
     X509V3_set_ctx(&ext_ctx, issuer_cert, x, NULL, NULL, X509V3_CTX_REPLACE);
@@ -1080,6 +1093,7 @@ int x509_main(int argc, char **argv)
     NCONF_free(extconf);
     NCONF_free(extconf);
     BIO_free_all(out);
     BIO_free_all(out);
     X509_STORE_free(ctx);
     X509_STORE_free(ctx);
+    X509_NAME_free(fissu);
     X509_NAME_free(fsubj);
     X509_NAME_free(fsubj);
     X509_REQ_free(req);
     X509_REQ_free(req);
     X509_free(x);
     X509_free(x);

+ 25 - 0
libs/openssl/build.info

@@ -8,6 +8,7 @@ ENDIF
 IF[{- !$disabled{'deprecated-3.0'} -}]
 IF[{- !$disabled{'deprecated-3.0'} -}]
   SUBDIRS=engines
   SUBDIRS=engines
 ENDIF
 ENDIF
+SUBDIRS=exporters
 
 
 LIBS=libcrypto libssl
 LIBS=libcrypto libssl
 INCLUDE[libcrypto]=. include
 INCLUDE[libcrypto]=. include
@@ -99,3 +100,27 @@ IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-|BC-)/ -}]
   SHARED_SOURCE[libcrypto]=libcrypto.rc
   SHARED_SOURCE[libcrypto]=libcrypto.rc
   SHARED_SOURCE[libssl]=libssl.rc
   SHARED_SOURCE[libssl]=libssl.rc
 ENDIF
 ENDIF
+
+# This file sets the build directory up for CMake inclusion
+GENERATE[OpenSSLConfig.cmake]=exporters/cmake/OpenSSLConfig.cmake.in
+DEPEND[OpenSSLConfig.cmake]=builddata.pm
+GENERATE[OpenSSLConfigVersion.cmake]=exporters/cmake/OpenSSLConfigVersion.cmake.in
+DEPEND[OpenSSLConfigVersion.cmake]=builddata.pm
+DEPEND[OpenSSLConfigVersion.cmake]=OpenSSLConfig.cmake
+DEPEND[""]=OpenSSLConfigVersion.cmake
+
+# This file sets the build directory up for pkg-config
+GENERATE[libcrypto.pc]=exporters/pkg-config/libcrypto.pc.in
+DEPEND[libcrypto.pc]=builddata.pm
+GENERATE[libssl.pc]=exporters/pkg-config/libssl.pc.in
+DEPEND[libssl.pc]=builddata.pm
+GENERATE[openssl.pc]=exporters/pkg-config/openssl.pc.in
+DEPEND[openssl.pc]=builddata.pm
+DEPEND[openssl.pc]=libcrypto.pc libssl.pc
+
+GENERATE[builddata.pm]=util/mkinstallvars.pl \
+    PREFIX=. BINDIR=apps LIBDIR= INCLUDEDIR=include APPLINKDIR=ms \
+    ENGINESDIR=engines MODULESDIR=providers \
+    "VERSION=$(VERSION)" "LDLIBS=$(LIB_EX_LIBS)"
+
+DEPEND[""]=openssl.pc

+ 0 - 3
libs/openssl/crypto/aes/aes_x86core.c

@@ -81,13 +81,10 @@ static void prefetch256(const void *table)
 #define GETU32(p) (*((u32*)(p)))
 #define GETU32(p) (*((u32*)(p)))
 
 
 #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
 #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
-typedef unsigned __int64 u64;
 #define U64(C)  C##UI64
 #define U64(C)  C##UI64
 #elif defined(__arch64__)
 #elif defined(__arch64__)
-typedef unsigned long u64;
 #define U64(C)  C##UL
 #define U64(C)  C##UL
 #else
 #else
-typedef unsigned long long u64;
 #define U64(C)  C##ULL
 #define U64(C)  C##ULL
 #endif
 #endif
 
 

+ 710 - 0
libs/openssl/crypto/aes/asm/aes-riscv64-zvbb-zvkg-zvkned.pl

@@ -0,0 +1,710 @@
+#! /usr/bin/env perl
+# This file is dual-licensed, meaning that you can use it under your
+# choice of either of the following two licenses:
+#
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You can obtain
+# a copy in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+# or
+#
+# Copyright (c) 2023, Jerry Shih <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# - RV64I
+# - RISC-V Vector ('V') with VLEN >= 128
+# - RISC-V Vector Bit-manipulation extension ('Zvbb')
+# - RISC-V Vector GCM/GMAC extension ('Zvkg')
+# - RISC-V Vector AES block cipher extension ('Zvkned')
+# - RISC-V Zicclsm(Main memory supports misaligned loads/stores)
+
+use strict;
+use warnings;
+
+use FindBin qw($Bin);
+use lib "$Bin";
+use lib "$Bin/../../perlasm";
+use riscv;
+
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
+
+$output and open STDOUT,">$output";
+
+my $code=<<___;
+.text
+___
+
+{
+################################################################################
+# void rv64i_zvbb_zvkg_zvkned_aes_xts_encrypt(const unsigned char *in,
+#                                             unsigned char *out, size_t length,
+#                                             const AES_KEY *key1,
+#                                             const AES_KEY *key2,
+#                                             const unsigned char iv[16])
+my ($INPUT, $OUTPUT, $LENGTH, $KEY1, $KEY2, $IV) = ("a0", "a1", "a2", "a3", "a4", "a5");
+my ($TAIL_LENGTH) = ("a6");
+my ($VL) = ("a7");
+my ($T0, $T1, $T2) = ("t0", "t1", "t2");
+my ($STORE_LEN32) = ("t3");
+my ($LEN32) = ("t4");
+my ($V0, $V1, $V2, $V3, $V4, $V5, $V6, $V7,
+    $V8, $V9, $V10, $V11, $V12, $V13, $V14, $V15,
+    $V16, $V17, $V18, $V19, $V20, $V21, $V22, $V23,
+    $V24, $V25, $V26, $V27, $V28, $V29, $V30, $V31,
+) = map("v$_",(0..31));
+
+sub compute_xts_iv0 {
+    my $code=<<___;
+    # Load number of rounds
+    lwu $T0, 240($KEY2)
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V28, $IV]}
+    @{[vle32_v $V29, $KEY2]}
+    @{[vaesz_vs $V28, $V29]}
+    addi $T0, $T0, -1
+    addi $KEY2, $KEY2, 16
+1:
+    @{[vle32_v $V29, $KEY2]}
+    @{[vaesem_vs $V28, $V29]}
+    addi $T0, $T0, -1
+    addi $KEY2, $KEY2, 16
+    bnez $T0, 1b
+    @{[vle32_v $V29, $KEY2]}
+    @{[vaesef_vs $V28, $V29]}
+___
+
+    return $code;
+}
+
+# prepare input data(v24), iv(v28), bit-reversed-iv(v16), bit-reversed-iv-multiplier(v20)
+sub init_first_round {
+    my $code=<<___;
+    # load input
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    @{[vle32_v $V24, $INPUT]}
+
+    li $T0, 5
+    # We could simplify the initialization steps if we have `block<=1`.
+    blt $LEN32, $T0, 1f
+
+    # Note: We use `vgmul` for GF(2^128) multiplication. The `vgmul` uses
+    # different order of coefficients. We should use`vbrev8` to reverse the
+    # data when we use `vgmul`.
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vbrev8_v $V0, $V28]}
+    @{[vsetvli "zero", $LEN32, "e32", "m4", "ta", "ma"]}
+    @{[vmv_v_i $V16, 0]}
+    # v16: [r-IV0, r-IV0, ...]
+    @{[vaesz_vs $V16, $V0]}
+
+    # Prepare GF(2^128) multiplier [1, x, x^2, x^3, ...] in v8.
+    slli $T0, $LEN32, 2
+    @{[vsetvli "zero", $T0, "e32", "m1", "ta", "ma"]}
+    # v2: [`1`, `1`, `1`, `1`, ...]
+    @{[vmv_v_i $V2, 1]}
+    # v3: [`0`, `1`, `2`, `3`, ...]
+    @{[vid_v $V3]}
+    @{[vsetvli "zero", $T0, "e64", "m2", "ta", "ma"]}
+    # v4: [`1`, 0, `1`, 0, `1`, 0, `1`, 0, ...]
+    @{[vzext_vf2 $V4, $V2]}
+    # v6: [`0`, 0, `1`, 0, `2`, 0, `3`, 0, ...]
+    @{[vzext_vf2 $V6, $V3]}
+    slli $T0, $LEN32, 1
+    @{[vsetvli "zero", $T0, "e32", "m2", "ta", "ma"]}
+    # v8: [1<<0=1, 0, 0, 0, 1<<1=x, 0, 0, 0, 1<<2=x^2, 0, 0, 0, ...]
+    @{[vwsll_vv $V8, $V4, $V6]}
+
+    # Compute [r-IV0*1, r-IV0*x, r-IV0*x^2, r-IV0*x^3, ...] in v16
+    @{[vsetvli "zero", $LEN32, "e32", "m4", "ta", "ma"]}
+    @{[vbrev8_v $V8, $V8]}
+    @{[vgmul_vv $V16, $V8]}
+
+    # Compute [IV0*1, IV0*x, IV0*x^2, IV0*x^3, ...] in v28.
+    # Reverse the bits order back.
+    @{[vbrev8_v $V28, $V16]}
+
+    # Prepare the x^n multiplier in v20. The `n` is the aes-xts block number
+    # in a LMUL=4 register group.
+    #   n = ((VLEN*LMUL)/(32*4)) = ((VLEN*4)/(32*4))
+    #     = (VLEN/32)
+    # We could use vsetvli with `e32, m1` to compute the `n` number.
+    @{[vsetvli $T0, "zero", "e32", "m1", "ta", "ma"]}
+    li $T1, 1
+    sll $T0, $T1, $T0
+    @{[vsetivli "zero", 2, "e64", "m1", "ta", "ma"]}
+    @{[vmv_v_i $V0, 0]}
+    @{[vsetivli "zero", 1, "e64", "m1", "tu", "ma"]}
+    @{[vmv_v_x $V0, $T0]}
+    @{[vsetivli "zero", 2, "e64", "m1", "ta", "ma"]}
+    @{[vbrev8_v $V0, $V0]}
+    @{[vsetvli "zero", $LEN32, "e32", "m4", "ta", "ma"]}
+    @{[vmv_v_i $V20, 0]}
+    @{[vaesz_vs $V20, $V0]}
+
+    j 2f
+1:
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vbrev8_v $V16, $V28]}
+2:
+___
+
+    return $code;
+}
+
+# prepare xts enc last block's input(v24) and iv(v28)
+sub handle_xts_enc_last_block {
+    my $code=<<___;
+    bnez $TAIL_LENGTH, 1f
+    ret
+1:
+    # slidedown second to last block
+    addi $VL, $VL, -4
+    @{[vsetivli "zero", 4, "e32", "m4", "ta", "ma"]}
+    # ciphertext
+    @{[vslidedown_vx $V24, $V24, $VL]}
+    # multiplier
+    @{[vslidedown_vx $V16, $V16, $VL]}
+
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vmv_v_v $V25, $V24]}
+
+    # load last block into v24
+    # note: We should load the last block before store the second to last block
+    #       for in-place operation.
+    @{[vsetvli "zero", $TAIL_LENGTH, "e8", "m1", "tu", "ma"]}
+    @{[vle8_v $V24, $INPUT]}
+
+    # setup `x` multiplier with byte-reversed order
+    # 0b00000010 => 0b01000000 (0x40)
+    li $T0, 0x40
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vmv_v_i $V28, 0]}
+    @{[vsetivli "zero", 1, "e8", "m1", "tu", "ma"]}
+    @{[vmv_v_x $V28, $T0]}
+
+    # compute IV for last block
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vgmul_vv $V16, $V28]}
+    @{[vbrev8_v $V28, $V16]}
+
+    # store second to last block
+    @{[vsetvli "zero", $TAIL_LENGTH, "e8", "m1", "ta", "ma"]}
+    @{[vse8_v $V25, $OUTPUT]}
+___
+
+    return $code;
+}
+
+# prepare xts dec second to last block's input(v24) and iv(v29) and
+# last block's and iv(v28)
+sub handle_xts_dec_last_block {
+    my $code=<<___;
+    bnez $TAIL_LENGTH, 1f
+    ret
+1:
+    # load second to last block's ciphertext
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V24, $INPUT]}
+    addi $INPUT, $INPUT, 16
+
+    # setup `x` multiplier with byte-reversed order
+    # 0b00000010 => 0b01000000 (0x40)
+    li $T0, 0x40
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vmv_v_i $V20, 0]}
+    @{[vsetivli "zero", 1, "e8", "m1", "tu", "ma"]}
+    @{[vmv_v_x $V20, $T0]}
+
+    beqz $LENGTH, 1f
+    # slidedown third to last block
+    addi $VL, $VL, -4
+    @{[vsetivli "zero", 4, "e32", "m4", "ta", "ma"]}
+    # multiplier
+    @{[vslidedown_vx $V16, $V16, $VL]}
+
+    # compute IV for last block
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vgmul_vv $V16, $V20]}
+    @{[vbrev8_v $V28, $V16]}
+
+    # compute IV for second to last block
+    @{[vgmul_vv $V16, $V20]}
+    @{[vbrev8_v $V29, $V16]}
+    j 2f
+1:
+    # compute IV for second to last block
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vgmul_vv $V16, $V20]}
+    @{[vbrev8_v $V29, $V16]}
+2:
+___
+
+    return $code;
+}
+
+# Load all 11 round keys to v1-v11 registers.
+sub aes_128_load_key {
+    my $code=<<___;
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V1, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V2, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V3, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V4, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V5, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V6, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V7, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V8, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V9, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V10, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V11, $KEY1]}
+___
+
+    return $code;
+}
+
+# Load all 15 round keys to v1-v15 registers.
+sub aes_256_load_key {
+    my $code=<<___;
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V1, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V2, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V3, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V4, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V5, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V6, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V7, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V8, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V9, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V10, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V11, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V12, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V13, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V14, $KEY1]}
+    addi $KEY1, $KEY1, 16
+    @{[vle32_v $V15, $KEY1]}
+___
+
+    return $code;
+}
+
+# aes-128 enc with round keys v1-v11
+sub aes_128_enc {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V1]}
+    @{[vaesem_vs $V24, $V2]}
+    @{[vaesem_vs $V24, $V3]}
+    @{[vaesem_vs $V24, $V4]}
+    @{[vaesem_vs $V24, $V5]}
+    @{[vaesem_vs $V24, $V6]}
+    @{[vaesem_vs $V24, $V7]}
+    @{[vaesem_vs $V24, $V8]}
+    @{[vaesem_vs $V24, $V9]}
+    @{[vaesem_vs $V24, $V10]}
+    @{[vaesef_vs $V24, $V11]}
+___
+
+    return $code;
+}
+
+# aes-128 dec with round keys v1-v11
+sub aes_128_dec {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V11]}
+    @{[vaesdm_vs $V24, $V10]}
+    @{[vaesdm_vs $V24, $V9]}
+    @{[vaesdm_vs $V24, $V8]}
+    @{[vaesdm_vs $V24, $V7]}
+    @{[vaesdm_vs $V24, $V6]}
+    @{[vaesdm_vs $V24, $V5]}
+    @{[vaesdm_vs $V24, $V4]}
+    @{[vaesdm_vs $V24, $V3]}
+    @{[vaesdm_vs $V24, $V2]}
+    @{[vaesdf_vs $V24, $V1]}
+___
+
+    return $code;
+}
+
+# aes-256 enc with round keys v1-v15
+sub aes_256_enc {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V1]}
+    @{[vaesem_vs $V24, $V2]}
+    @{[vaesem_vs $V24, $V3]}
+    @{[vaesem_vs $V24, $V4]}
+    @{[vaesem_vs $V24, $V5]}
+    @{[vaesem_vs $V24, $V6]}
+    @{[vaesem_vs $V24, $V7]}
+    @{[vaesem_vs $V24, $V8]}
+    @{[vaesem_vs $V24, $V9]}
+    @{[vaesem_vs $V24, $V10]}
+    @{[vaesem_vs $V24, $V11]}
+    @{[vaesem_vs $V24, $V12]}
+    @{[vaesem_vs $V24, $V13]}
+    @{[vaesem_vs $V24, $V14]}
+    @{[vaesef_vs $V24, $V15]}
+___
+
+    return $code;
+}
+
+# aes-256 dec with round keys v1-v15
+sub aes_256_dec {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V15]}
+    @{[vaesdm_vs $V24, $V14]}
+    @{[vaesdm_vs $V24, $V13]}
+    @{[vaesdm_vs $V24, $V12]}
+    @{[vaesdm_vs $V24, $V11]}
+    @{[vaesdm_vs $V24, $V10]}
+    @{[vaesdm_vs $V24, $V9]}
+    @{[vaesdm_vs $V24, $V8]}
+    @{[vaesdm_vs $V24, $V7]}
+    @{[vaesdm_vs $V24, $V6]}
+    @{[vaesdm_vs $V24, $V5]}
+    @{[vaesdm_vs $V24, $V4]}
+    @{[vaesdm_vs $V24, $V3]}
+    @{[vaesdm_vs $V24, $V2]}
+    @{[vaesdf_vs $V24, $V1]}
+___
+
+    return $code;
+}
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvbb_zvkg_zvkned_aes_xts_encrypt
+.type rv64i_zvbb_zvkg_zvkned_aes_xts_encrypt,\@function
+rv64i_zvbb_zvkg_zvkned_aes_xts_encrypt:
+    @{[compute_xts_iv0]}
+
+    # aes block size is 16
+    andi $TAIL_LENGTH, $LENGTH, 15
+    mv $STORE_LEN32, $LENGTH
+    beqz $TAIL_LENGTH, 1f
+    sub $LENGTH, $LENGTH, $TAIL_LENGTH
+    addi $STORE_LEN32, $LENGTH, -16
+1:
+    # We make the `LENGTH` become e32 length here.
+    srli $LEN32, $LENGTH, 2
+    srli $STORE_LEN32, $STORE_LEN32, 2
+
+    # Load number of rounds
+    lwu $T0, 240($KEY1)
+    li $T1, 14
+    li $T2, 10
+    beq $T0, $T1, aes_xts_enc_256
+    beq $T0, $T2, aes_xts_enc_128
+.size rv64i_zvbb_zvkg_zvkned_aes_xts_encrypt,.-rv64i_zvbb_zvkg_zvkned_aes_xts_encrypt
+___
+
+$code .= <<___;
+.p2align 3
+aes_xts_enc_128:
+    @{[init_first_round]}
+    @{[aes_128_load_key]}
+
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    j 1f
+
+.Lenc_blocks_128:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    # load plaintext into v24
+    @{[vle32_v $V24, $INPUT]}
+    # update iv
+    @{[vgmul_vv $V16, $V20]}
+    # reverse the iv's bits order back
+    @{[vbrev8_v $V28, $V16]}
+1:
+    @{[vxor_vv $V24, $V24, $V28]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+    add $INPUT, $INPUT, $T0
+    @{[aes_128_enc]}
+    @{[vxor_vv $V24, $V24, $V28]}
+
+    # store ciphertext
+    @{[vsetvli "zero", $STORE_LEN32, "e32", "m4", "ta", "ma"]}
+    @{[vse32_v $V24, $OUTPUT]}
+    add $OUTPUT, $OUTPUT, $T0
+    sub $STORE_LEN32, $STORE_LEN32, $VL
+
+    bnez $LEN32, .Lenc_blocks_128
+
+    @{[handle_xts_enc_last_block]}
+
+    # xts last block
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vxor_vv $V24, $V24, $V28]}
+    @{[aes_128_enc]}
+    @{[vxor_vv $V24, $V24, $V28]}
+
+    # store last block ciphertext
+    addi $OUTPUT, $OUTPUT, -16
+    @{[vse32_v $V24, $OUTPUT]}
+
+    ret
+.size aes_xts_enc_128,.-aes_xts_enc_128
+___
+
+$code .= <<___;
+.p2align 3
+aes_xts_enc_256:
+    @{[init_first_round]}
+    @{[aes_256_load_key]}
+
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    j 1f
+
+.Lenc_blocks_256:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    # load plaintext into v24
+    @{[vle32_v $V24, $INPUT]}
+    # update iv
+    @{[vgmul_vv $V16, $V20]}
+    # reverse the iv's bits order back
+    @{[vbrev8_v $V28, $V16]}
+1:
+    @{[vxor_vv $V24, $V24, $V28]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+    add $INPUT, $INPUT, $T0
+    @{[aes_256_enc]}
+    @{[vxor_vv $V24, $V24, $V28]}
+
+    # store ciphertext
+    @{[vsetvli "zero", $STORE_LEN32, "e32", "m4", "ta", "ma"]}
+    @{[vse32_v $V24, $OUTPUT]}
+    add $OUTPUT, $OUTPUT, $T0
+    sub $STORE_LEN32, $STORE_LEN32, $VL
+
+    bnez $LEN32, .Lenc_blocks_256
+
+    @{[handle_xts_enc_last_block]}
+
+    # xts last block
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vxor_vv $V24, $V24, $V28]}
+    @{[aes_256_enc]}
+    @{[vxor_vv $V24, $V24, $V28]}
+
+    # store last block ciphertext
+    addi $OUTPUT, $OUTPUT, -16
+    @{[vse32_v $V24, $OUTPUT]}
+
+    ret
+.size aes_xts_enc_256,.-aes_xts_enc_256
+___
+
+################################################################################
+# void rv64i_zvbb_zvkg_zvkned_aes_xts_decrypt(const unsigned char *in,
+#                                             unsigned char *out, size_t length,
+#                                             const AES_KEY *key1,
+#                                             const AES_KEY *key2,
+#                                             const unsigned char iv[16])
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvbb_zvkg_zvkned_aes_xts_decrypt
+.type rv64i_zvbb_zvkg_zvkned_aes_xts_decrypt,\@function
+rv64i_zvbb_zvkg_zvkned_aes_xts_decrypt:
+    @{[compute_xts_iv0]}
+
+    # aes block size is 16
+    andi $TAIL_LENGTH, $LENGTH, 15
+    beqz $TAIL_LENGTH, 1f
+    sub $LENGTH, $LENGTH, $TAIL_LENGTH
+    addi $LENGTH, $LENGTH, -16
+1:
+    # We make the `LENGTH` become e32 length here.
+    srli $LEN32, $LENGTH, 2
+
+    # Load number of rounds
+    lwu $T0, 240($KEY1)
+    li $T1, 14
+    li $T2, 10
+    beq $T0, $T1, aes_xts_dec_256
+    beq $T0, $T2, aes_xts_dec_128
+.size rv64i_zvbb_zvkg_zvkned_aes_xts_decrypt,.-rv64i_zvbb_zvkg_zvkned_aes_xts_decrypt
+___
+
+$code .= <<___;
+.p2align 3
+aes_xts_dec_128:
+    @{[init_first_round]}
+    @{[aes_128_load_key]}
+
+    beqz $LEN32, 2f
+
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    j 1f
+
+.Ldec_blocks_128:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    # load ciphertext into v24
+    @{[vle32_v $V24, $INPUT]}
+    # update iv
+    @{[vgmul_vv $V16, $V20]}
+    # reverse the iv's bits order back
+    @{[vbrev8_v $V28, $V16]}
+1:
+    @{[vxor_vv $V24, $V24, $V28]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+    add $INPUT, $INPUT, $T0
+    @{[aes_128_dec]}
+    @{[vxor_vv $V24, $V24, $V28]}
+
+    # store plaintext
+    @{[vse32_v $V24, $OUTPUT]}
+    add $OUTPUT, $OUTPUT, $T0
+
+    bnez $LEN32, .Ldec_blocks_128
+
+2:
+    @{[handle_xts_dec_last_block]}
+
+    ## xts second to last block
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vxor_vv $V24, $V24, $V29]}
+    @{[aes_128_dec]}
+    @{[vxor_vv $V24, $V24, $V29]}
+    @{[vmv_v_v $V25, $V24]}
+
+    # load last block ciphertext
+    @{[vsetvli "zero", $TAIL_LENGTH, "e8", "m1", "tu", "ma"]}
+    @{[vle8_v $V24, $INPUT]}
+
+    # store second to last block plaintext
+    addi $T0, $OUTPUT, 16
+    @{[vse8_v $V25, $T0]}
+
+    ## xts last block
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vxor_vv $V24, $V24, $V28]}
+    @{[aes_128_dec]}
+    @{[vxor_vv $V24, $V24, $V28]}
+
+    # store second to last block plaintext
+    @{[vse32_v $V24, $OUTPUT]}
+
+    ret
+.size aes_xts_dec_128,.-aes_xts_dec_128
+___
+
+$code .= <<___;
+.p2align 3
+aes_xts_dec_256:
+    @{[init_first_round]}
+    @{[aes_256_load_key]}
+
+    beqz $LEN32, 2f
+
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    j 1f
+
+.Ldec_blocks_256:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    # load ciphertext into v24
+    @{[vle32_v $V24, $INPUT]}
+    # update iv
+    @{[vgmul_vv $V16, $V20]}
+    # reverse the iv's bits order back
+    @{[vbrev8_v $V28, $V16]}
+1:
+    @{[vxor_vv $V24, $V24, $V28]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+    add $INPUT, $INPUT, $T0
+    @{[aes_256_dec]}
+    @{[vxor_vv $V24, $V24, $V28]}
+
+    # store plaintext
+    @{[vse32_v $V24, $OUTPUT]}
+    add $OUTPUT, $OUTPUT, $T0
+
+    bnez $LEN32, .Ldec_blocks_256
+
+2:
+    @{[handle_xts_dec_last_block]}
+
+    ## xts second to last block
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vxor_vv $V24, $V24, $V29]}
+    @{[aes_256_dec]}
+    @{[vxor_vv $V24, $V24, $V29]}
+    @{[vmv_v_v $V25, $V24]}
+
+    # load last block ciphertext
+    @{[vsetvli "zero", $TAIL_LENGTH, "e8", "m1", "tu", "ma"]}
+    @{[vle8_v $V24, $INPUT]}
+
+    # store second to last block plaintext
+    addi $T0, $OUTPUT, 16
+    @{[vse8_v $V25, $T0]}
+
+    ## xts last block
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vxor_vv $V24, $V24, $V28]}
+    @{[aes_256_dec]}
+    @{[vxor_vv $V24, $V24, $V28]}
+
+    # store second to last block plaintext
+    @{[vse32_v $V24, $OUTPUT]}
+
+    ret
+.size aes_xts_dec_256,.-aes_xts_dec_256
+___
+}
+
+print $code;
+
+close STDOUT or die "error closing STDOUT: $!";

+ 376 - 0
libs/openssl/crypto/aes/asm/aes-riscv64-zvkb-zvkned.pl

@@ -0,0 +1,376 @@
+#! /usr/bin/env perl
+# This file is dual-licensed, meaning that you can use it under your
+# choice of either of the following two licenses:
+#
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You can obtain
+# a copy in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+# or
+#
+# Copyright (c) 2023, Jerry Shih <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# - RV64I
+# - RISC-V Vector ('V') with VLEN >= 128
+# - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb')
+# - RISC-V Vector AES block cipher extension ('Zvkned')
+# - RISC-V Zicclsm(Main memory supports misaligned loads/stores)
+
+use strict;
+use warnings;
+
+use FindBin qw($Bin);
+use lib "$Bin";
+use lib "$Bin/../../perlasm";
+use riscv;
+
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
+
+$output and open STDOUT,">$output";
+
+my $code=<<___;
+.text
+___
+
+################################################################################
+# void rv64i_zvkb_zvkned_ctr32_encrypt_blocks(const unsigned char *in,
+#                                             unsigned char *out, size_t blocks,
+#                                             const void *key,
+#                                             const unsigned char ivec[16]);
+{
+my ($INP, $OUTP, $BLOCK_NUM, $KEYP, $IVP) = ("a0", "a1", "a2", "a3", "a4");
+my ($T0, $T1, $T2, $T3) = ("t0", "t1", "t2", "t3");
+my ($VL) = ("t4");
+my ($LEN32) = ("t5");
+my ($CTR) = ("t6");
+my ($MASK) = ("v0");
+my ($V0, $V1, $V2, $V3, $V4, $V5, $V6, $V7,
+    $V8, $V9, $V10, $V11, $V12, $V13, $V14, $V15,
+    $V16, $V17, $V18, $V19, $V20, $V21, $V22, $V23,
+    $V24, $V25, $V26, $V27, $V28, $V29, $V30, $V31,
+) = map("v$_",(0..31));
+
+# Prepare the AES ctr input data into v16.
+sub init_aes_ctr_input {
+    my $code=<<___;
+    # Setup mask into v0
+    # The mask pattern for 4*N-th elements
+    # mask v0: [000100010001....]
+    # Note:
+    #   We could setup the mask just for the maximum element length instead of
+    #   the VLMAX.
+    li $T0, 0b10001000
+    @{[vsetvli $T2, "zero", "e8", "m1", "ta", "ma"]}
+    @{[vmv_v_x $MASK, $T0]}
+    # Load IV.
+    # v31:[IV0, IV1, IV2, big-endian count]
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V31, $IVP]}
+    # Convert the big-endian counter into little-endian.
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "mu"]}
+    @{[vrev8_v $V31, $V31, $MASK]}
+    # Splat the IV to v16
+    @{[vsetvli "zero", $LEN32, "e32", "m4", "ta", "ma"]}
+    @{[vmv_v_i $V16, 0]}
+    @{[vaesz_vs $V16, $V31]}
+    # Prepare the ctr pattern into v20
+    # v20: [x, x, x, 0, x, x, x, 1, x, x, x, 2, ...]
+    @{[viota_m $V20, $MASK, $MASK]}
+    # v16:[IV0, IV1, IV2, count+0, IV0, IV1, IV2, count+1, ...]
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "mu"]}
+    @{[vadd_vv $V16, $V16, $V20, $MASK]}
+___
+
+    return $code;
+}
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvkb_zvkned_ctr32_encrypt_blocks
+.type rv64i_zvkb_zvkned_ctr32_encrypt_blocks,\@function
+rv64i_zvkb_zvkned_ctr32_encrypt_blocks:
+    beqz $BLOCK_NUM, 1f
+
+    # Load number of rounds
+    lwu $T0, 240($KEYP)
+    li $T1, 14
+    li $T2, 12
+    li $T3, 10
+
+    slli $LEN32, $BLOCK_NUM, 2
+
+    beq $T0, $T1, ctr32_encrypt_blocks_256
+    beq $T0, $T2, ctr32_encrypt_blocks_192
+    beq $T0, $T3, ctr32_encrypt_blocks_128
+
+1:
+    ret
+
+.size rv64i_zvkb_zvkned_ctr32_encrypt_blocks,.-rv64i_zvkb_zvkned_ctr32_encrypt_blocks
+___
+
+$code .= <<___;
+.p2align 3
+ctr32_encrypt_blocks_128:
+    # Load all 11 round keys to v1-v11 registers.
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V1, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V2, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V3, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V4, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V5, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V6, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V7, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V8, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V9, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V10, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V11, $KEYP]}
+
+    @{[init_aes_ctr_input]}
+
+    ##### AES body
+    j 2f
+1:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "mu"]}
+    # Increase ctr in v16.
+    @{[vadd_vx $V16, $V16, $CTR, $MASK]}
+2:
+    # Load plaintext into v20
+    @{[vle32_v $V20, $INP]}
+    slli $T0, $VL, 2
+    srli $CTR, $VL, 2
+    sub $LEN32, $LEN32, $VL
+    add $INP, $INP, $T0
+    # Prepare the AES ctr input into v24.
+    # The ctr data uses big-endian form.
+    @{[vmv_v_v $V24, $V16]}
+    @{[vrev8_v $V24, $V24, $MASK]}
+
+    @{[vaesz_vs $V24, $V1]}
+    @{[vaesem_vs $V24, $V2]}
+    @{[vaesem_vs $V24, $V3]}
+    @{[vaesem_vs $V24, $V4]}
+    @{[vaesem_vs $V24, $V5]}
+    @{[vaesem_vs $V24, $V6]}
+    @{[vaesem_vs $V24, $V7]}
+    @{[vaesem_vs $V24, $V8]}
+    @{[vaesem_vs $V24, $V9]}
+    @{[vaesem_vs $V24, $V10]}
+    @{[vaesef_vs $V24, $V11]}
+
+    # ciphertext
+    @{[vxor_vv $V24, $V24, $V20]}
+
+    # Store the ciphertext.
+    @{[vse32_v $V24, $OUTP]}
+    add $OUTP, $OUTP, $T0
+
+    bnez $LEN32, 1b
+
+    ret
+.size ctr32_encrypt_blocks_128,.-ctr32_encrypt_blocks_128
+___
+
+$code .= <<___;
+.p2align 3
+ctr32_encrypt_blocks_192:
+    # Load all 13 round keys to v1-v13 registers.
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V1, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V2, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V3, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V4, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V5, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V6, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V7, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V8, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V9, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V10, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V11, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V12, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V13, $KEYP]}
+
+    @{[init_aes_ctr_input]}
+
+    ##### AES body
+    j 2f
+1:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "mu"]}
+    # Increase ctr in v16.
+    @{[vadd_vx $V16, $V16, $CTR, $MASK]}
+2:
+    # Load plaintext into v20
+    @{[vle32_v $V20, $INP]}
+    slli $T0, $VL, 2
+    srli $CTR, $VL, 2
+    sub $LEN32, $LEN32, $VL
+    add $INP, $INP, $T0
+    # Prepare the AES ctr input into v24.
+    # The ctr data uses big-endian form.
+    @{[vmv_v_v $V24, $V16]}
+    @{[vrev8_v $V24, $V24, $MASK]}
+
+    @{[vaesz_vs $V24, $V1]}
+    @{[vaesem_vs $V24, $V2]}
+    @{[vaesem_vs $V24, $V3]}
+    @{[vaesem_vs $V24, $V4]}
+    @{[vaesem_vs $V24, $V5]}
+    @{[vaesem_vs $V24, $V6]}
+    @{[vaesem_vs $V24, $V7]}
+    @{[vaesem_vs $V24, $V8]}
+    @{[vaesem_vs $V24, $V9]}
+    @{[vaesem_vs $V24, $V10]}
+    @{[vaesem_vs $V24, $V11]}
+    @{[vaesem_vs $V24, $V12]}
+    @{[vaesef_vs $V24, $V13]}
+
+    # ciphertext
+    @{[vxor_vv $V24, $V24, $V20]}
+
+    # Store the ciphertext.
+    @{[vse32_v $V24, $OUTP]}
+    add $OUTP, $OUTP, $T0
+
+    bnez $LEN32, 1b
+
+    ret
+.size ctr32_encrypt_blocks_192,.-ctr32_encrypt_blocks_192
+___
+
+$code .= <<___;
+.p2align 3
+ctr32_encrypt_blocks_256:
+    # Load all 15 round keys to v1-v15 registers.
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V1, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V2, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V3, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V4, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V5, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V6, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V7, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V8, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V9, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V10, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V11, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V12, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V13, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V14, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V15, $KEYP]}
+
+    @{[init_aes_ctr_input]}
+
+    ##### AES body
+    j 2f
+1:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "mu"]}
+    # Increase ctr in v16.
+    @{[vadd_vx $V16, $V16, $CTR, $MASK]}
+2:
+    # Load plaintext into v20
+    @{[vle32_v $V20, $INP]}
+    slli $T0, $VL, 2
+    srli $CTR, $VL, 2
+    sub $LEN32, $LEN32, $VL
+    add $INP, $INP, $T0
+    # Prepare the AES ctr input into v24.
+    # The ctr data uses big-endian form.
+    @{[vmv_v_v $V24, $V16]}
+    @{[vrev8_v $V24, $V24, $MASK]}
+
+    @{[vaesz_vs $V24, $V1]}
+    @{[vaesem_vs $V24, $V2]}
+    @{[vaesem_vs $V24, $V3]}
+    @{[vaesem_vs $V24, $V4]}
+    @{[vaesem_vs $V24, $V5]}
+    @{[vaesem_vs $V24, $V6]}
+    @{[vaesem_vs $V24, $V7]}
+    @{[vaesem_vs $V24, $V8]}
+    @{[vaesem_vs $V24, $V9]}
+    @{[vaesem_vs $V24, $V10]}
+    @{[vaesem_vs $V24, $V11]}
+    @{[vaesem_vs $V24, $V12]}
+    @{[vaesem_vs $V24, $V13]}
+    @{[vaesem_vs $V24, $V14]}
+    @{[vaesef_vs $V24, $V15]}
+
+    # ciphertext
+    @{[vxor_vv $V24, $V24, $V20]}
+
+    # Store the ciphertext.
+    @{[vse32_v $V24, $OUTP]}
+    add $OUTP, $OUTP, $T0
+
+    bnez $LEN32, 1b
+
+    ret
+.size ctr32_encrypt_blocks_256,.-ctr32_encrypt_blocks_256
+___
+}
+
+print $code;
+
+close STDOUT or die "error closing STDOUT: $!";

+ 1376 - 0
libs/openssl/crypto/aes/asm/aes-riscv64-zvkned.pl

@@ -0,0 +1,1376 @@
+#! /usr/bin/env perl
+# This file is dual-licensed, meaning that you can use it under your
+# choice of either of the following two licenses:
+#
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You can obtain
+# a copy in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+# or
+#
+# Copyright (c) 2023, Christoph Müllner <[email protected]>
+# Copyright (c) 2023, Phoebe Chen <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# - RV64I
+# - RISC-V Vector ('V') with VLEN >= 128
+# - RISC-V Vector AES block cipher extension ('Zvkned')
+
+use strict;
+use warnings;
+
+use FindBin qw($Bin);
+use lib "$Bin";
+use lib "$Bin/../../perlasm";
+use riscv;
+
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
+
+$output and open STDOUT,">$output";
+
+my $code=<<___;
+.text
+___
+
+my ($V0, $V1, $V2, $V3, $V4, $V5, $V6, $V7,
+    $V8, $V9, $V10, $V11, $V12, $V13, $V14, $V15,
+    $V16, $V17, $V18, $V19, $V20, $V21, $V22, $V23,
+    $V24, $V25, $V26, $V27, $V28, $V29, $V30, $V31,
+) = map("v$_",(0..31));
+
+# Load all 11 round keys to v1-v11 registers.
+sub aes_128_load_key {
+    my $KEYP = shift;
+
+    my $code=<<___;
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V1, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V2, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V3, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V4, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V5, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V6, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V7, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V8, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V9, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V10, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V11, $KEYP]}
+___
+
+    return $code;
+}
+
+# Load all 13 round keys to v1-v13 registers.
+sub aes_192_load_key {
+    my $KEYP = shift;
+
+    my $code=<<___;
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V1, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V2, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V3, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V4, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V5, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V6, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V7, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V8, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V9, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V10, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V11, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V12, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V13, $KEYP]}
+___
+
+    return $code;
+}
+
+# Load all 15 round keys to v1-v15 registers.
+sub aes_256_load_key {
+    my $KEYP = shift;
+
+    my $code=<<___;
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+    @{[vle32_v $V1, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V2, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V3, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V4, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V5, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V6, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V7, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V8, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V9, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V10, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V11, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V12, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V13, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V14, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V15, $KEYP]}
+___
+
+    return $code;
+}
+
+# aes-128 encryption with round keys v1-v11
+sub aes_128_encrypt {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V1]}     # with round key w[ 0, 3]
+    @{[vaesem_vs $V24, $V2]}    # with round key w[ 4, 7]
+    @{[vaesem_vs $V24, $V3]}    # with round key w[ 8,11]
+    @{[vaesem_vs $V24, $V4]}    # with round key w[12,15]
+    @{[vaesem_vs $V24, $V5]}    # with round key w[16,19]
+    @{[vaesem_vs $V24, $V6]}    # with round key w[20,23]
+    @{[vaesem_vs $V24, $V7]}    # with round key w[24,27]
+    @{[vaesem_vs $V24, $V8]}    # with round key w[28,31]
+    @{[vaesem_vs $V24, $V9]}    # with round key w[32,35]
+    @{[vaesem_vs $V24, $V10]}   # with round key w[36,39]
+    @{[vaesef_vs $V24, $V11]}   # with round key w[40,43]
+___
+
+    return $code;
+}
+
+# aes-128 decryption with round keys v1-v11
+sub aes_128_decrypt {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V11]}   # with round key w[40,43]
+    @{[vaesdm_vs $V24, $V10]}  # with round key w[36,39]
+    @{[vaesdm_vs $V24, $V9]}   # with round key w[32,35]
+    @{[vaesdm_vs $V24, $V8]}   # with round key w[28,31]
+    @{[vaesdm_vs $V24, $V7]}   # with round key w[24,27]
+    @{[vaesdm_vs $V24, $V6]}   # with round key w[20,23]
+    @{[vaesdm_vs $V24, $V5]}   # with round key w[16,19]
+    @{[vaesdm_vs $V24, $V4]}   # with round key w[12,15]
+    @{[vaesdm_vs $V24, $V3]}   # with round key w[ 8,11]
+    @{[vaesdm_vs $V24, $V2]}   # with round key w[ 4, 7]
+    @{[vaesdf_vs $V24, $V1]}   # with round key w[ 0, 3]
+___
+
+    return $code;
+}
+
+# aes-192 encryption with round keys v1-v13
+sub aes_192_encrypt {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V1]}     # with round key w[ 0, 3]
+    @{[vaesem_vs $V24, $V2]}    # with round key w[ 4, 7]
+    @{[vaesem_vs $V24, $V3]}    # with round key w[ 8,11]
+    @{[vaesem_vs $V24, $V4]}    # with round key w[12,15]
+    @{[vaesem_vs $V24, $V5]}    # with round key w[16,19]
+    @{[vaesem_vs $V24, $V6]}    # with round key w[20,23]
+    @{[vaesem_vs $V24, $V7]}    # with round key w[24,27]
+    @{[vaesem_vs $V24, $V8]}    # with round key w[28,31]
+    @{[vaesem_vs $V24, $V9]}    # with round key w[32,35]
+    @{[vaesem_vs $V24, $V10]}   # with round key w[36,39]
+    @{[vaesem_vs $V24, $V11]}   # with round key w[40,43]
+    @{[vaesem_vs $V24, $V12]}   # with round key w[44,47]
+    @{[vaesef_vs $V24, $V13]}   # with round key w[48,51]
+___
+
+    return $code;
+}
+
+# aes-192 decryption with round keys v1-v13
+sub aes_192_decrypt {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V13]}    # with round key w[48,51]
+    @{[vaesdm_vs $V24, $V12]}   # with round key w[44,47]
+    @{[vaesdm_vs $V24, $V11]}   # with round key w[40,43]
+    @{[vaesdm_vs $V24, $V10]}   # with round key w[36,39]
+    @{[vaesdm_vs $V24, $V9]}    # with round key w[32,35]
+    @{[vaesdm_vs $V24, $V8]}    # with round key w[28,31]
+    @{[vaesdm_vs $V24, $V7]}    # with round key w[24,27]
+    @{[vaesdm_vs $V24, $V6]}    # with round key w[20,23]
+    @{[vaesdm_vs $V24, $V5]}    # with round key w[16,19]
+    @{[vaesdm_vs $V24, $V4]}    # with round key w[12,15]
+    @{[vaesdm_vs $V24, $V3]}    # with round key w[ 8,11]
+    @{[vaesdm_vs $V24, $V2]}    # with round key w[ 4, 7]
+    @{[vaesdf_vs $V24, $V1]}    # with round key w[ 0, 3]
+___
+
+    return $code;
+}
+
+# aes-256 encryption with round keys v1-v15
+sub aes_256_encrypt {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V1]}     # with round key w[ 0, 3]
+    @{[vaesem_vs $V24, $V2]}    # with round key w[ 4, 7]
+    @{[vaesem_vs $V24, $V3]}    # with round key w[ 8,11]
+    @{[vaesem_vs $V24, $V4]}    # with round key w[12,15]
+    @{[vaesem_vs $V24, $V5]}    # with round key w[16,19]
+    @{[vaesem_vs $V24, $V6]}    # with round key w[20,23]
+    @{[vaesem_vs $V24, $V7]}    # with round key w[24,27]
+    @{[vaesem_vs $V24, $V8]}    # with round key w[28,31]
+    @{[vaesem_vs $V24, $V9]}    # with round key w[32,35]
+    @{[vaesem_vs $V24, $V10]}   # with round key w[36,39]
+    @{[vaesem_vs $V24, $V11]}   # with round key w[40,43]
+    @{[vaesem_vs $V24, $V12]}   # with round key w[44,47]
+    @{[vaesem_vs $V24, $V13]}   # with round key w[48,51]
+    @{[vaesem_vs $V24, $V14]}   # with round key w[52,55]
+    @{[vaesef_vs $V24, $V15]}   # with round key w[56,59]
+___
+
+    return $code;
+}
+
+# aes-256 decryption with round keys v1-v15
+sub aes_256_decrypt {
+    my $code=<<___;
+    @{[vaesz_vs $V24, $V15]}    # with round key w[56,59]
+    @{[vaesdm_vs $V24, $V14]}   # with round key w[52,55]
+    @{[vaesdm_vs $V24, $V13]}   # with round key w[48,51]
+    @{[vaesdm_vs $V24, $V12]}   # with round key w[44,47]
+    @{[vaesdm_vs $V24, $V11]}   # with round key w[40,43]
+    @{[vaesdm_vs $V24, $V10]}   # with round key w[36,39]
+    @{[vaesdm_vs $V24, $V9]}    # with round key w[32,35]
+    @{[vaesdm_vs $V24, $V8]}    # with round key w[28,31]
+    @{[vaesdm_vs $V24, $V7]}    # with round key w[24,27]
+    @{[vaesdm_vs $V24, $V6]}    # with round key w[20,23]
+    @{[vaesdm_vs $V24, $V5]}    # with round key w[16,19]
+    @{[vaesdm_vs $V24, $V4]}    # with round key w[12,15]
+    @{[vaesdm_vs $V24, $V3]}    # with round key w[ 8,11]
+    @{[vaesdm_vs $V24, $V2]}    # with round key w[ 4, 7]
+    @{[vaesdf_vs $V24, $V1]}    # with round key w[ 0, 3]
+___
+
+    return $code;
+}
+
+{
+###############################################################################
+# void rv64i_zvkned_cbc_encrypt(const unsigned char *in, unsigned char *out,
+#                               size_t length, const AES_KEY *key,
+#                               unsigned char *ivec, const int enc);
+my ($INP, $OUTP, $LEN, $KEYP, $IVP, $ENC) = ("a0", "a1", "a2", "a3", "a4", "a5");
+my ($T0, $T1, $ROUNDS) = ("t0", "t1", "t2");
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvkned_cbc_encrypt
+.type rv64i_zvkned_cbc_encrypt,\@function
+rv64i_zvkned_cbc_encrypt:
+    # check whether the length is a multiple of 16 and >= 16
+    li $T1, 16
+    blt $LEN, $T1, L_end
+    andi $T1, $LEN, 15
+    bnez $T1, L_end
+
+    # Load number of rounds
+    lwu $ROUNDS, 240($KEYP)
+
+    # Get proper routine for key size
+    li $T0, 10
+    beq $ROUNDS, $T0, L_cbc_enc_128
+
+    li $T0, 12
+    beq $ROUNDS, $T0, L_cbc_enc_192
+
+    li $T0, 14
+    beq $ROUNDS, $T0, L_cbc_enc_256
+
+    ret
+.size rv64i_zvkned_cbc_encrypt,.-rv64i_zvkned_cbc_encrypt
+___
+
+$code .= <<___;
+.p2align 3
+L_cbc_enc_128:
+    # Load all 11 round keys to v1-v11 registers.
+    @{[aes_128_load_key $KEYP]}
+
+    # Load IV.
+    @{[vle32_v $V16, $IVP]}
+
+    @{[vle32_v $V24, $INP]}
+    @{[vxor_vv $V24, $V24, $V16]}
+    j 2f
+
+1:
+    @{[vle32_v $V17, $INP]}
+    @{[vxor_vv $V24, $V24, $V17]}
+
+2:
+    # AES body
+    @{[aes_128_encrypt]}
+
+    @{[vse32_v $V24, $OUTP]}
+
+    addi $INP, $INP, 16
+    addi $OUTP, $OUTP, 16
+    addi $LEN, $LEN, -16
+
+    bnez $LEN, 1b
+
+    @{[vse32_v $V24, $IVP]}
+
+    ret
+.size L_cbc_enc_128,.-L_cbc_enc_128
+___
+
+$code .= <<___;
+.p2align 3
+L_cbc_enc_192:
+    # Load all 13 round keys to v1-v13 registers.
+    @{[aes_192_load_key $KEYP]}
+
+    # Load IV.
+    @{[vle32_v $V16, $IVP]}
+
+    @{[vle32_v $V24, $INP]}
+    @{[vxor_vv $V24, $V24, $V16]}
+    j 2f
+
+1:
+    @{[vle32_v $V17, $INP]}
+    @{[vxor_vv $V24, $V24, $V17]}
+
+2:
+    # AES body
+    @{[aes_192_encrypt]}
+
+    @{[vse32_v $V24, $OUTP]}
+
+    addi $INP, $INP, 16
+    addi $OUTP, $OUTP, 16
+    addi $LEN, $LEN, -16
+
+    bnez $LEN, 1b
+
+    @{[vse32_v $V24, $IVP]}
+
+    ret
+.size L_cbc_enc_192,.-L_cbc_enc_192
+___
+
+$code .= <<___;
+.p2align 3
+L_cbc_enc_256:
+    # Load all 15 round keys to v1-v15 registers.
+    @{[aes_256_load_key $KEYP]}
+
+    # Load IV.
+    @{[vle32_v $V16, $IVP]}
+
+    @{[vle32_v $V24, $INP]}
+    @{[vxor_vv $V24, $V24, $V16]}
+    j 2f
+
+1:
+    @{[vle32_v $V17, $INP]}
+    @{[vxor_vv $V24, $V24, $V17]}
+
+2:
+    # AES body
+    @{[aes_256_encrypt]}
+
+    @{[vse32_v $V24, $OUTP]}
+
+    addi $INP, $INP, 16
+    addi $OUTP, $OUTP, 16
+    addi $LEN, $LEN, -16
+
+    bnez $LEN, 1b
+
+    @{[vse32_v $V24, $IVP]}
+
+    ret
+.size L_cbc_enc_256,.-L_cbc_enc_256
+___
+
+###############################################################################
+# void rv64i_zvkned_cbc_decrypt(const unsigned char *in, unsigned char *out,
+#                               size_t length, const AES_KEY *key,
+#                               unsigned char *ivec, const int enc);
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvkned_cbc_decrypt
+.type rv64i_zvkned_cbc_decrypt,\@function
+rv64i_zvkned_cbc_decrypt:
+    # check whether the length is a multiple of 16 and >= 16
+    li $T1, 16
+    blt $LEN, $T1, L_end
+    andi $T1, $LEN, 15
+    bnez $T1, L_end
+
+    # Load number of rounds
+    lwu $ROUNDS, 240($KEYP)
+
+    # Get proper routine for key size
+    li $T0, 10
+    beq $ROUNDS, $T0, L_cbc_dec_128
+
+    li $T0, 12
+    beq $ROUNDS, $T0, L_cbc_dec_192
+
+    li $T0, 14
+    beq $ROUNDS, $T0, L_cbc_dec_256
+
+    ret
+.size rv64i_zvkned_cbc_decrypt,.-rv64i_zvkned_cbc_decrypt
+___
+
+$code .= <<___;
+.p2align 3
+L_cbc_dec_128:
+    # Load all 11 round keys to v1-v11 registers.
+    @{[aes_128_load_key $KEYP]}
+
+    # Load IV.
+    @{[vle32_v $V16, $IVP]}
+
+    @{[vle32_v $V24, $INP]}
+    @{[vmv_v_v $V17, $V24]}
+    j 2f
+
+1:
+    @{[vle32_v $V24, $INP]}
+    @{[vmv_v_v $V17, $V24]}
+    addi $OUTP, $OUTP, 16
+
+2:
+    # AES body
+    @{[aes_128_decrypt]}
+
+    @{[vxor_vv $V24, $V24, $V16]}
+    @{[vse32_v $V24, $OUTP]}
+    @{[vmv_v_v $V16, $V17]}
+
+    addi $LEN, $LEN, -16
+    addi $INP, $INP, 16
+
+    bnez $LEN, 1b
+
+    @{[vse32_v $V16, $IVP]}
+
+    ret
+.size L_cbc_dec_128,.-L_cbc_dec_128
+___
+
+$code .= <<___;
+.p2align 3
+L_cbc_dec_192:
+    # Load all 13 round keys to v1-v13 registers.
+    @{[aes_192_load_key $KEYP]}
+
+    # Load IV.
+    @{[vle32_v $V16, $IVP]}
+
+    @{[vle32_v $V24, $INP]}
+    @{[vmv_v_v $V17, $V24]}
+    j 2f
+
+1:
+    @{[vle32_v $V24, $INP]}
+    @{[vmv_v_v $V17, $V24]}
+    addi $OUTP, $OUTP, 16
+
+2:
+    # AES body
+    @{[aes_192_decrypt]}
+
+    @{[vxor_vv $V24, $V24, $V16]}
+    @{[vse32_v $V24, $OUTP]}
+    @{[vmv_v_v $V16, $V17]}
+
+    addi $LEN, $LEN, -16
+    addi $INP, $INP, 16
+
+    bnez $LEN, 1b
+
+    @{[vse32_v $V16, $IVP]}
+
+    ret
+.size L_cbc_dec_192,.-L_cbc_dec_192
+___
+
+$code .= <<___;
+.p2align 3
+L_cbc_dec_256:
+    # Load all 15 round keys to v1-v15 registers.
+    @{[aes_256_load_key $KEYP]}
+
+    # Load IV.
+    @{[vle32_v $V16, $IVP]}
+
+    @{[vle32_v $V24, $INP]}
+    @{[vmv_v_v $V17, $V24]}
+    j 2f
+
+1:
+    @{[vle32_v $V24, $INP]}
+    @{[vmv_v_v $V17, $V24]}
+    addi $OUTP, $OUTP, 16
+
+2:
+    # AES body
+    @{[aes_256_decrypt]}
+
+    @{[vxor_vv $V24, $V24, $V16]}
+    @{[vse32_v $V24, $OUTP]}
+    @{[vmv_v_v $V16, $V17]}
+
+    addi $LEN, $LEN, -16
+    addi $INP, $INP, 16
+
+    bnez $LEN, 1b
+
+    @{[vse32_v $V16, $IVP]}
+
+    ret
+.size L_cbc_dec_256,.-L_cbc_dec_256
+___
+}
+
+{
+###############################################################################
+# void rv64i_zvkned_ecb_encrypt(const unsigned char *in, unsigned char *out,
+#                               size_t length, const AES_KEY *key,
+#                               const int enc);
+my ($INP, $OUTP, $LEN, $KEYP, $ENC) = ("a0", "a1", "a2", "a3", "a4");
+my ($REMAIN_LEN) = ("a5");
+my ($VL) = ("a6");
+my ($T0, $T1, $ROUNDS) = ("t0", "t1", "t2");
+my ($LEN32) = ("t3");
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvkned_ecb_encrypt
+.type rv64i_zvkned_ecb_encrypt,\@function
+rv64i_zvkned_ecb_encrypt:
+    # Make the LEN become e32 length.
+    srli $LEN32, $LEN, 2
+
+    # Load number of rounds
+    lwu $ROUNDS, 240($KEYP)
+
+    # Get proper routine for key size
+    li $T0, 10
+    beq $ROUNDS, $T0, L_ecb_enc_128
+
+    li $T0, 12
+    beq $ROUNDS, $T0, L_ecb_enc_192
+
+    li $T0, 14
+    beq $ROUNDS, $T0, L_ecb_enc_256
+
+    ret
+.size rv64i_zvkned_ecb_encrypt,.-rv64i_zvkned_ecb_encrypt
+___
+
+$code .= <<___;
+.p2align 3
+L_ecb_enc_128:
+    # Load all 11 round keys to v1-v11 registers.
+    @{[aes_128_load_key $KEYP]}
+
+1:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+
+    @{[vle32_v $V24, $INP]}
+
+    # AES body
+    @{[aes_128_encrypt]}
+
+    @{[vse32_v $V24, $OUTP]}
+
+    add $INP, $INP, $T0
+    add $OUTP, $OUTP, $T0
+
+    bnez $LEN32, 1b
+
+    ret
+.size L_ecb_enc_128,.-L_ecb_enc_128
+___
+
+$code .= <<___;
+.p2align 3
+L_ecb_enc_192:
+    # Load all 13 round keys to v1-v13 registers.
+    @{[aes_192_load_key $KEYP]}
+
+1:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+
+    @{[vle32_v $V24, $INP]}
+
+    # AES body
+    @{[aes_192_encrypt]}
+
+    @{[vse32_v $V24, $OUTP]}
+
+    add $INP, $INP, $T0
+    add $OUTP, $OUTP, $T0
+
+    bnez $LEN32, 1b
+
+    ret
+.size L_ecb_enc_192,.-L_ecb_enc_192
+___
+
+$code .= <<___;
+.p2align 3
+L_ecb_enc_256:
+    # Load all 15 round keys to v1-v15 registers.
+    @{[aes_256_load_key $KEYP]}
+
+1:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+
+    @{[vle32_v $V24, $INP]}
+
+    # AES body
+    @{[aes_256_encrypt]}
+
+    @{[vse32_v $V24, $OUTP]}
+
+    add $INP, $INP, $T0
+    add $OUTP, $OUTP, $T0
+
+    bnez $LEN32, 1b
+
+    ret
+.size L_ecb_enc_256,.-L_ecb_enc_256
+___
+
+###############################################################################
+# void rv64i_zvkned_ecb_decrypt(const unsigned char *in, unsigned char *out,
+#                               size_t length, const AES_KEY *key,
+#                               const int enc);
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvkned_ecb_decrypt
+.type rv64i_zvkned_ecb_decrypt,\@function
+rv64i_zvkned_ecb_decrypt:
+    # Make the LEN become e32 length.
+    srli $LEN32, $LEN, 2
+
+    # Load number of rounds
+    lwu $ROUNDS, 240($KEYP)
+
+    # Get proper routine for key size
+    li $T0, 10
+    beq $ROUNDS, $T0, L_ecb_dec_128
+
+    li $T0, 12
+    beq $ROUNDS, $T0, L_ecb_dec_192
+
+    li $T0, 14
+    beq $ROUNDS, $T0, L_ecb_dec_256
+
+    ret
+.size rv64i_zvkned_ecb_decrypt,.-rv64i_zvkned_ecb_decrypt
+___
+
+$code .= <<___;
+.p2align 3
+L_ecb_dec_128:
+    # Load all 11 round keys to v1-v11 registers.
+    @{[aes_128_load_key $KEYP]}
+
+1:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+
+    @{[vle32_v $V24, $INP]}
+
+    # AES body
+    @{[aes_128_decrypt]}
+
+    @{[vse32_v $V24, $OUTP]}
+
+    add $INP, $INP, $T0
+    add $OUTP, $OUTP, $T0
+
+    bnez $LEN32, 1b
+
+    ret
+.size L_ecb_dec_128,.-L_ecb_dec_128
+___
+
+$code .= <<___;
+.p2align 3
+L_ecb_dec_192:
+    # Load all 13 round keys to v1-v13 registers.
+    @{[aes_192_load_key $KEYP]}
+
+1:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+
+    @{[vle32_v $V24, $INP]}
+
+    # AES body
+    @{[aes_192_decrypt]}
+
+    @{[vse32_v $V24, $OUTP]}
+
+    add $INP, $INP, $T0
+    add $OUTP, $OUTP, $T0
+
+    bnez $LEN32, 1b
+
+    ret
+.size L_ecb_dec_192,.-L_ecb_dec_192
+___
+
+$code .= <<___;
+.p2align 3
+L_ecb_dec_256:
+    # Load all 15 round keys to v1-v15 registers.
+    @{[aes_256_load_key $KEYP]}
+
+1:
+    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
+    slli $T0, $VL, 2
+    sub $LEN32, $LEN32, $VL
+
+    @{[vle32_v $V24, $INP]}
+
+    # AES body
+    @{[aes_256_decrypt]}
+
+    @{[vse32_v $V24, $OUTP]}
+
+    add $INP, $INP, $T0
+    add $OUTP, $OUTP, $T0
+
+    bnez $LEN32, 1b
+
+    ret
+.size L_ecb_dec_256,.-L_ecb_dec_256
+___
+
+}
+
+{
+################################################################################
+# int rv64i_zvkned_set_encrypt_key(const unsigned char *userKey, const int bits,
+#                                  AES_KEY *key)
+# int rv64i_zvkned_set_decrypt_key(const unsigned char *userKey, const int bits,
+#                                  AES_KEY *key)
+my ($UKEY,$BITS,$KEYP) = ("a0", "a1", "a2");
+my ($T0,$T1,$T4) = ("t1", "t2", "t4");
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvkned_set_encrypt_key
+.type rv64i_zvkned_set_encrypt_key,\@function
+rv64i_zvkned_set_encrypt_key:
+    beqz $UKEY, L_fail_m1
+    beqz $KEYP, L_fail_m1
+
+    # Get proper routine for key size
+    li $T0, 256
+    beq $BITS, $T0, L_set_key_256
+    li $T0, 128
+    beq $BITS, $T0, L_set_key_128
+
+    j L_fail_m2
+
+.size rv64i_zvkned_set_encrypt_key,.-rv64i_zvkned_set_encrypt_key
+___
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvkned_set_decrypt_key
+.type rv64i_zvkned_set_decrypt_key,\@function
+rv64i_zvkned_set_decrypt_key:
+    beqz $UKEY, L_fail_m1
+    beqz $KEYP, L_fail_m1
+
+    # Get proper routine for key size
+    li $T0, 256
+    beq $BITS, $T0, L_set_key_256
+    li $T0, 128
+    beq $BITS, $T0, L_set_key_128
+
+    j L_fail_m2
+
+.size rv64i_zvkned_set_decrypt_key,.-rv64i_zvkned_set_decrypt_key
+___
+
+$code .= <<___;
+.p2align 3
+L_set_key_128:
+    # Store the number of rounds
+    li $T1, 10
+    sw $T1, 240($KEYP)
+
+    @{[vsetivli__x0_4_e32_m1_tu_mu]}
+
+    # Load the key
+    @{[vle32_v $V10, ($UKEY)]}
+
+    # Generate keys for round 2-11 into registers v11-v20.
+    @{[vaeskf1_vi $V11, $V10, 1]}   # v11 <- rk2  (w[ 4, 7])
+    @{[vaeskf1_vi $V12, $V11, 2]}   # v12 <- rk3  (w[ 8,11])
+    @{[vaeskf1_vi $V13, $V12, 3]}   # v13 <- rk4  (w[12,15])
+    @{[vaeskf1_vi $V14, $V13, 4]}   # v14 <- rk5  (w[16,19])
+    @{[vaeskf1_vi $V15, $V14, 5]}   # v15 <- rk6  (w[20,23])
+    @{[vaeskf1_vi $V16, $V15, 6]}   # v16 <- rk7  (w[24,27])
+    @{[vaeskf1_vi $V17, $V16, 7]}   # v17 <- rk8  (w[28,31])
+    @{[vaeskf1_vi $V18, $V17, 8]}   # v18 <- rk9  (w[32,35])
+    @{[vaeskf1_vi $V19, $V18, 9]}   # v19 <- rk10 (w[36,39])
+    @{[vaeskf1_vi $V20, $V19, 10]}  # v20 <- rk11 (w[40,43])
+
+    # Store the round keys
+    @{[vse32_v $V10, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V11, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V12, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V13, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V14, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V15, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V16, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V17, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V18, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V19, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V20, $KEYP]}
+
+    li a0, 1
+    ret
+.size L_set_key_128,.-L_set_key_128
+___
+
+$code .= <<___;
+.p2align 3
+L_set_key_256:
+    # Store the number of rounds
+    li $T1, 14
+    sw $T1, 240($KEYP)
+
+    @{[vsetivli__x0_4_e32_m1_tu_mu]}
+
+    # Load the key
+    @{[vle32_v $V10, ($UKEY)]}
+    addi $UKEY, $UKEY, 16
+    @{[vle32_v $V11, ($UKEY)]}
+
+    @{[vmv_v_v $V12, $V10]}
+    @{[vaeskf2_vi $V12, $V11, 2]}
+    @{[vmv_v_v $V13, $V11]}
+    @{[vaeskf2_vi $V13, $V12, 3]}
+    @{[vmv_v_v $V14, $V12]}
+    @{[vaeskf2_vi $V14, $V13, 4]}
+    @{[vmv_v_v $V15, $V13]}
+    @{[vaeskf2_vi $V15, $V14, 5]}
+    @{[vmv_v_v $V16, $V14]}
+    @{[vaeskf2_vi $V16, $V15, 6]}
+    @{[vmv_v_v $V17, $V15]}
+    @{[vaeskf2_vi $V17, $V16, 7]}
+    @{[vmv_v_v $V18, $V16]}
+    @{[vaeskf2_vi $V18, $V17, 8]}
+    @{[vmv_v_v $V19, $V17]}
+    @{[vaeskf2_vi $V19, $V18, 9]}
+    @{[vmv_v_v $V20, $V18]}
+    @{[vaeskf2_vi $V20, $V19, 10]}
+    @{[vmv_v_v $V21, $V19]}
+    @{[vaeskf2_vi $V21, $V20, 11]}
+    @{[vmv_v_v $V22, $V20]}
+    @{[vaeskf2_vi $V22, $V21, 12]}
+    @{[vmv_v_v $V23, $V21]}
+    @{[vaeskf2_vi $V23, $V22, 13]}
+    @{[vmv_v_v $V24, $V22]}
+    @{[vaeskf2_vi $V24, $V23, 14]}
+
+    @{[vse32_v $V10, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V11, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V12, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V13, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V14, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V15, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V16, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V17, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V18, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V19, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V20, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V21, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V22, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V23, $KEYP]}
+    addi $KEYP, $KEYP, 16
+    @{[vse32_v $V24, $KEYP]}
+
+    li a0, 1
+    ret
+.size L_set_key_256,.-L_set_key_256
+___
+}
+
+{
+################################################################################
+# void rv64i_zvkned_encrypt(const unsigned char *in, unsigned char *out,
+#                           const AES_KEY *key);
+my ($INP,$OUTP,$KEYP) = ("a0", "a1", "a2");
+my ($T0,$T1, $ROUNDS, $T6) = ("a3", "a4", "t5", "t6");
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvkned_encrypt
+.type rv64i_zvkned_encrypt,\@function
+rv64i_zvkned_encrypt:
+    # Load number of rounds
+    lwu $ROUNDS, 240($KEYP)
+
+    # Get proper routine for key size
+    li $T6, 14
+    beq $ROUNDS, $T6, L_enc_256
+    li $T6, 10
+    beq $ROUNDS, $T6, L_enc_128
+    li $T6, 12
+    beq $ROUNDS, $T6, L_enc_192
+
+    j L_fail_m2
+.size rv64i_zvkned_encrypt,.-rv64i_zvkned_encrypt
+___
+
+$code .= <<___;
+.p2align 3
+L_enc_128:
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+
+    @{[vle32_v $V1, $INP]}
+
+    @{[vle32_v $V10, $KEYP]}
+    @{[vaesz_vs $V1, $V10]}    # with round key w[ 0, 3]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V11, $KEYP]}
+    @{[vaesem_vs $V1, $V11]}   # with round key w[ 4, 7]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V12, $KEYP]}
+    @{[vaesem_vs $V1, $V12]}   # with round key w[ 8,11]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V13, $KEYP]}
+    @{[vaesem_vs $V1, $V13]}   # with round key w[12,15]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V14, $KEYP]}
+    @{[vaesem_vs $V1, $V14]}   # with round key w[16,19]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V15, $KEYP]}
+    @{[vaesem_vs $V1, $V15]}   # with round key w[20,23]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V16, $KEYP]}
+    @{[vaesem_vs $V1, $V16]}   # with round key w[24,27]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V17, $KEYP]}
+    @{[vaesem_vs $V1, $V17]}   # with round key w[28,31]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V18, $KEYP]}
+    @{[vaesem_vs $V1, $V18]}   # with round key w[32,35]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V19, $KEYP]}
+    @{[vaesem_vs $V1, $V19]}   # with round key w[36,39]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V20, $KEYP]}
+    @{[vaesef_vs $V1, $V20]}   # with round key w[40,43]
+
+    @{[vse32_v $V1, $OUTP]}
+
+    ret
+.size L_enc_128,.-L_enc_128
+___
+
+$code .= <<___;
+.p2align 3
+L_enc_192:
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+
+    @{[vle32_v $V1, $INP]}
+
+    @{[vle32_v $V10, $KEYP]}
+    @{[vaesz_vs $V1, $V10]}     # with round key w[ 0, 3]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V11, $KEYP]}
+    @{[vaesem_vs $V1, $V11]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V12, $KEYP]}
+    @{[vaesem_vs $V1, $V12]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V13, $KEYP]}
+    @{[vaesem_vs $V1, $V13]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V14, $KEYP]}
+    @{[vaesem_vs $V1, $V14]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V15, $KEYP]}
+    @{[vaesem_vs $V1, $V15]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V16, $KEYP]}
+    @{[vaesem_vs $V1, $V16]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V17, $KEYP]}
+    @{[vaesem_vs $V1, $V17]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V18, $KEYP]}
+    @{[vaesem_vs $V1, $V18]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V19, $KEYP]}
+    @{[vaesem_vs $V1, $V19]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V20, $KEYP]}
+    @{[vaesem_vs $V1, $V20]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V21, $KEYP]}
+    @{[vaesem_vs $V1, $V21]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V22, $KEYP]}
+    @{[vaesef_vs $V1, $V22]}
+
+    @{[vse32_v $V1, $OUTP]}
+    ret
+.size L_enc_192,.-L_enc_192
+___
+
+$code .= <<___;
+.p2align 3
+L_enc_256:
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+
+    @{[vle32_v $V1, $INP]}
+
+    @{[vle32_v $V10, $KEYP]}
+    @{[vaesz_vs $V1, $V10]}     # with round key w[ 0, 3]
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V11, $KEYP]}
+    @{[vaesem_vs $V1, $V11]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V12, $KEYP]}
+    @{[vaesem_vs $V1, $V12]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V13, $KEYP]}
+    @{[vaesem_vs $V1, $V13]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V14, $KEYP]}
+    @{[vaesem_vs $V1, $V14]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V15, $KEYP]}
+    @{[vaesem_vs $V1, $V15]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V16, $KEYP]}
+    @{[vaesem_vs $V1, $V16]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V17, $KEYP]}
+    @{[vaesem_vs $V1, $V17]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V18, $KEYP]}
+    @{[vaesem_vs $V1, $V18]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V19, $KEYP]}
+    @{[vaesem_vs $V1, $V19]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V20, $KEYP]}
+    @{[vaesem_vs $V1, $V20]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V21, $KEYP]}
+    @{[vaesem_vs $V1, $V21]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V22, $KEYP]}
+    @{[vaesem_vs $V1, $V22]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V23, $KEYP]}
+    @{[vaesem_vs $V1, $V23]}
+    addi $KEYP, $KEYP, 16
+    @{[vle32_v $V24, $KEYP]}
+    @{[vaesef_vs $V1, $V24]}
+
+    @{[vse32_v $V1, $OUTP]}
+    ret
+.size L_enc_256,.-L_enc_256
+___
+
+################################################################################
+# void rv64i_zvkned_decrypt(const unsigned char *in, unsigned char *out,
+#                           const AES_KEY *key);
+
+$code .= <<___;
+.p2align 3
+.globl rv64i_zvkned_decrypt
+.type rv64i_zvkned_decrypt,\@function
+rv64i_zvkned_decrypt:
+    # Load number of rounds
+    lwu $ROUNDS, 240($KEYP)
+
+    # Get proper routine for key size
+    li $T6, 14
+    beq $ROUNDS, $T6, L_dec_256
+    li $T6, 10
+    beq $ROUNDS, $T6, L_dec_128
+    li $T6, 12
+    beq $ROUNDS, $T6, L_dec_192
+
+    j L_fail_m2
+.size rv64i_zvkned_decrypt,.-rv64i_zvkned_decrypt
+___
+
+$code .= <<___;
+.p2align 3
+L_dec_128:
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+
+    @{[vle32_v $V1, $INP]}
+
+    addi $KEYP, $KEYP, 160
+    @{[vle32_v $V20, $KEYP]}
+    @{[vaesz_vs $V1, $V20]}    # with round key w[40,43]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V19, $KEYP]}
+    @{[vaesdm_vs $V1, $V19]}   # with round key w[36,39]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V18, $KEYP]}
+    @{[vaesdm_vs $V1, $V18]}   # with round key w[32,35]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V17, $KEYP]}
+    @{[vaesdm_vs $V1, $V17]}   # with round key w[28,31]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V16, $KEYP]}
+    @{[vaesdm_vs $V1, $V16]}   # with round key w[24,27]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V15, $KEYP]}
+    @{[vaesdm_vs $V1, $V15]}   # with round key w[20,23]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V14, $KEYP]}
+    @{[vaesdm_vs $V1, $V14]}   # with round key w[16,19]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V13, $KEYP]}
+    @{[vaesdm_vs $V1, $V13]}   # with round key w[12,15]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V12, $KEYP]}
+    @{[vaesdm_vs $V1, $V12]}   # with round key w[ 8,11]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V11, $KEYP]}
+    @{[vaesdm_vs $V1, $V11]}   # with round key w[ 4, 7]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V10, $KEYP]}
+    @{[vaesdf_vs $V1, $V10]}   # with round key w[ 0, 3]
+
+    @{[vse32_v $V1, $OUTP]}
+
+    ret
+.size L_dec_128,.-L_dec_128
+___
+
+$code .= <<___;
+.p2align 3
+L_dec_192:
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+
+    @{[vle32_v $V1, $INP]}
+
+    addi $KEYP, $KEYP, 192
+    @{[vle32_v $V22, $KEYP]}
+    @{[vaesz_vs $V1, $V22]}    # with round key w[48,51]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V21, $KEYP]}
+    @{[vaesdm_vs $V1, $V21]}   # with round key w[44,47]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V20, $KEYP]}
+    @{[vaesdm_vs $V1, $V20]}    # with round key w[40,43]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V19, $KEYP]}
+    @{[vaesdm_vs $V1, $V19]}   # with round key w[36,39]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V18, $KEYP]}
+    @{[vaesdm_vs $V1, $V18]}   # with round key w[32,35]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V17, $KEYP]}
+    @{[vaesdm_vs $V1, $V17]}   # with round key w[28,31]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V16, $KEYP]}
+    @{[vaesdm_vs $V1, $V16]}   # with round key w[24,27]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V15, $KEYP]}
+    @{[vaesdm_vs $V1, $V15]}   # with round key w[20,23]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V14, $KEYP]}
+    @{[vaesdm_vs $V1, $V14]}   # with round key w[16,19]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V13, $KEYP]}
+    @{[vaesdm_vs $V1, $V13]}   # with round key w[12,15]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V12, $KEYP]}
+    @{[vaesdm_vs $V1, $V12]}   # with round key w[ 8,11]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V11, $KEYP]}
+    @{[vaesdm_vs $V1, $V11]}   # with round key w[ 4, 7]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V10, $KEYP]}
+    @{[vaesdf_vs $V1, $V10]}   # with round key w[ 0, 3]
+
+    @{[vse32_v $V1, $OUTP]}
+
+    ret
+.size L_dec_192,.-L_dec_192
+___
+
+$code .= <<___;
+.p2align 3
+L_dec_256:
+    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
+
+    @{[vle32_v $V1, $INP]}
+
+    addi $KEYP, $KEYP, 224
+    @{[vle32_v $V24, $KEYP]}
+    @{[vaesz_vs $V1, $V24]}    # with round key w[56,59]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V23, $KEYP]}
+    @{[vaesdm_vs $V1, $V23]}   # with round key w[52,55]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V22, $KEYP]}
+    @{[vaesdm_vs $V1, $V22]}    # with round key w[48,51]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V21, $KEYP]}
+    @{[vaesdm_vs $V1, $V21]}   # with round key w[44,47]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V20, $KEYP]}
+    @{[vaesdm_vs $V1, $V20]}    # with round key w[40,43]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V19, $KEYP]}
+    @{[vaesdm_vs $V1, $V19]}   # with round key w[36,39]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V18, $KEYP]}
+    @{[vaesdm_vs $V1, $V18]}   # with round key w[32,35]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V17, $KEYP]}
+    @{[vaesdm_vs $V1, $V17]}   # with round key w[28,31]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V16, $KEYP]}
+    @{[vaesdm_vs $V1, $V16]}   # with round key w[24,27]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V15, $KEYP]}
+    @{[vaesdm_vs $V1, $V15]}   # with round key w[20,23]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V14, $KEYP]}
+    @{[vaesdm_vs $V1, $V14]}   # with round key w[16,19]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V13, $KEYP]}
+    @{[vaesdm_vs $V1, $V13]}   # with round key w[12,15]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V12, $KEYP]}
+    @{[vaesdm_vs $V1, $V12]}   # with round key w[ 8,11]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V11, $KEYP]}
+    @{[vaesdm_vs $V1, $V11]}   # with round key w[ 4, 7]
+    addi $KEYP, $KEYP, -16
+    @{[vle32_v $V10, $KEYP]}
+    @{[vaesdf_vs $V1, $V10]}   # with round key w[ 0, 3]
+
+    @{[vse32_v $V1, $OUTP]}
+
+    ret
+.size L_dec_256,.-L_dec_256
+___
+}
+
+$code .= <<___;
+L_fail_m1:
+    li a0, -1
+    ret
+.size L_fail_m1,.-L_fail_m1
+
+L_fail_m2:
+    li a0, -2
+    ret
+.size L_fail_m2,.-L_fail_m2
+
+L_end:
+  ret
+.size L_end,.-L_end
+___
+
+print $code;
+
+close STDOUT or die "error closing STDOUT: $!";

+ 1 - 1
libs/openssl/crypto/aes/asm/aesp8-ppc.pl

@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
 #! /usr/bin/env perl
-# Copyright 2014-2023 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
 #
 #
 # Licensed under the Apache License 2.0 (the "License").  You may not use
 # 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
 # this file except in compliance with the License.  You can obtain a copy

+ 765 - 3
libs/openssl/crypto/aes/asm/aesv8-armx.pl

@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
 #! /usr/bin/env perl
-# Copyright 2014-2023 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2014-2024 The OpenSSL Project Authors. All Rights Reserved.
 #
 #
 # Licensed under the Apache License 2.0 (the "License").  You may not use
 # 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
 # this file except in compliance with the License.  You can obtain a copy
@@ -1751,6 +1751,755 @@ $code.=<<___;
 .size	${prefix}_cbc_encrypt,.-${prefix}_cbc_encrypt
 .size	${prefix}_cbc_encrypt,.-${prefix}_cbc_encrypt
 ___
 ___
 }}}
 }}}
+
+{{{
+my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4));
+my ($rounds,$roundsx,$cnt,$key_)=("w5","x5","w6","x7");
+my ($ctr,$tctr0,$tctr1,$tctr2)=map("w$_",(8..10,12));
+my ($tctr3,$tctr4,$tctr5,$tctr6)=map("w$_",(11,13..15));
+my ($tctr7,$tctr8,$tctr9,$tctr10,$tctr11)=map("w$_",(19..23));
+
+# q0-q7 => v0-v7; q8-q23 => v16-v31; q24-q31 => v8-v15
+my ($ivec,$rndlast,$rndping,$rndpang)=map("q$_",(0..3));
+my ($in0,$in1,$in2,$in3,$in4,$in5)=map("q$_",(4..9));
+my ($in6,$in7,$in8,$in9,$in10,$in11)=map("q$_",(10..15));
+my ($dat0,$dat1,$dat2,$dat3,$dat4,$dat5)=map("q$_",(16..21));
+my ($dat6,$dat7,$dat8,$dat9,$dat10,$dat11)=map("q$_",(22..27));
+my ($tmp0,$tmp1,$tmp2)=map("q$_",(25..27));
+
+#q_X => qX, for ldp & stp
+my ($in0q,$in1q,$in2q,$in3q)=map("q_$_",(4..7));
+my ($in4q,$in5q,$in6q,$in7q,$in8q,$in9q,$in10q,$in11q)=map("q_$_",(16..23));
+
+my ($dat8d,$dat9d,$dat10d,$dat11d)=map("d$_",(8..11));
+
+$code.=<<___	if ($flavour =~ /64/);
+.globl	${prefix}_ctr32_encrypt_blocks_unroll12_eor3
+.type	${prefix}_ctr32_encrypt_blocks_unroll12_eor3,%function
+.align	5
+${prefix}_ctr32_encrypt_blocks_unroll12_eor3:
+	AARCH64_VALID_CALL_TARGET
+	// Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later.
+	stp		x29,x30,[sp,#-80]!
+	stp		d8,d9,[sp, #16]
+	stp		d10,d11,[sp, #32]
+	stp		d12,d13,[sp, #48]
+	stp		d14,d15,[sp, #64]
+	add		x29,sp,#0
+
+	 ldr		$rounds,[$key,#240]
+
+	 ldr		$ctr, [$ivp, #12]
+#ifdef __AARCH64EB__
+	vld1.8		{$dat0},[$ivp]
+#else
+	vld1.32		{$dat0},[$ivp]
+#endif
+	vld1.32		{$rndping-$rndpang},[$key]		// load key schedule...
+	 sub		$rounds,$rounds,#4
+	 cmp		$len,#2
+	 add		$key_,$key,$roundsx,lsl#4	// pointer to last round key
+	 sub		$rounds,$rounds,#2
+	 add		$key_, $key_, #64
+	vld1.32		{$rndlast},[$key_]
+	 add		$key_,$key,#32
+	 mov		$cnt,$rounds
+#ifndef __AARCH64EB__
+	rev		$ctr, $ctr
+#endif
+
+	vorr		$dat1,$dat0,$dat0
+	 add		$tctr1, $ctr, #1
+	vorr		$dat2,$dat0,$dat0
+	 add		$ctr, $ctr, #2
+	vorr		$ivec,$dat0,$dat0
+	 rev		$tctr1, $tctr1
+	vmov.32		${dat1}[3],$tctr1
+	b.ls		.Lctr32_tail_unroll
+	 cmp		$len,#6
+	 rev		$tctr2, $ctr
+	 sub		$len,$len,#3		// bias
+	vmov.32		${dat2}[3],$tctr2
+	b.lo		.Loop3x_ctr32_unroll
+	 cmp		$len,#9
+	vorr		$dat3,$dat0,$dat0
+	 add		$tctr3, $ctr, #1
+	vorr		$dat4,$dat0,$dat0
+	 add		$tctr4, $ctr, #2
+	 rev		$tctr3, $tctr3
+	vorr		$dat5,$dat0,$dat0
+	 add		$ctr, $ctr, #3
+	 rev		$tctr4, $tctr4
+	vmov.32		${dat3}[3],$tctr3
+	 rev		$tctr5, $ctr
+	vmov.32		${dat4}[3],$tctr4
+	vmov.32		${dat5}[3],$tctr5
+	 sub		$len,$len,#3
+	b.lo		.Loop6x_ctr32_unroll
+
+	// push regs to stack when 12 data chunks are interleaved
+	 stp		x19,x20,[sp,#-16]!
+	 stp		x21,x22,[sp,#-16]!
+	 stp		x23,x24,[sp,#-16]!
+	 stp		$dat8d,$dat9d,[sp,#-32]!
+	 stp		$dat10d,$dat11d,[sp,#-32]!
+
+	 add		$tctr6,$ctr,#1
+	 add		$tctr7,$ctr,#2
+	 add		$tctr8,$ctr,#3
+	 add		$tctr9,$ctr,#4
+	 add		$tctr10,$ctr,#5
+	 add		$ctr,$ctr,#6
+	vorr		$dat6,$dat0,$dat0
+	 rev		$tctr6,$tctr6
+	vorr		$dat7,$dat0,$dat0
+	 rev		$tctr7,$tctr7
+	vorr		$dat8,$dat0,$dat0
+	 rev		$tctr8,$tctr8
+	vorr		$dat9,$dat0,$dat0
+	 rev		$tctr9,$tctr9
+	vorr		$dat10,$dat0,$dat0
+	 rev		$tctr10,$tctr10
+	vorr		$dat11,$dat0,$dat0
+	 rev		$tctr11,$ctr
+
+	 sub		$len,$len,#6		// bias
+	vmov.32		${dat6}[3],$tctr6
+	vmov.32		${dat7}[3],$tctr7
+	vmov.32		${dat8}[3],$tctr8
+	vmov.32		${dat9}[3],$tctr9
+	vmov.32		${dat10}[3],$tctr10
+	vmov.32		${dat11}[3],$tctr11
+	b		.Loop12x_ctr32_unroll
+
+.align	4
+.Loop12x_ctr32_unroll:
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndping
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndping
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndping
+	aesmc		$dat5,$dat5
+	aese		$dat6,$rndping
+	aesmc		$dat6,$dat6
+	aese		$dat7,$rndping
+	aesmc		$dat7,$dat7
+	aese		$dat8,$rndping
+	aesmc		$dat8,$dat8
+	aese		$dat9,$rndping
+	aesmc		$dat9,$dat9
+	aese		$dat10,$rndping
+	aesmc		$dat10,$dat10
+	aese		$dat11,$rndping
+	aesmc		$dat11,$dat11
+	vld1.32		{$rndping},[$key_],#16
+	subs		$cnt,$cnt,#2
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndpang
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndpang
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndpang
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndpang
+	aesmc		$dat5,$dat5
+	aese		$dat6,$rndpang
+	aesmc		$dat6,$dat6
+	aese		$dat7,$rndpang
+	aesmc		$dat7,$dat7
+	aese		$dat8,$rndpang
+	aesmc		$dat8,$dat8
+	aese		$dat9,$rndpang
+	aesmc		$dat9,$dat9
+	aese		$dat10,$rndpang
+	aesmc		$dat10,$dat10
+	aese		$dat11,$rndpang
+	aesmc		$dat11,$dat11
+	vld1.32		{$rndpang},[$key_],#16
+	b.gt		.Loop12x_ctr32_unroll
+
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndping
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndping
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndping
+	aesmc		$dat5,$dat5
+	aese		$dat6,$rndping
+	aesmc		$dat6,$dat6
+	aese		$dat7,$rndping
+	aesmc		$dat7,$dat7
+	aese		$dat8,$rndping
+	aesmc		$dat8,$dat8
+	aese		$dat9,$rndping
+	aesmc		$dat9,$dat9
+	aese		$dat10,$rndping
+	aesmc		$dat10,$dat10
+	aese		$dat11,$rndping
+	aesmc		$dat11,$dat11
+	vld1.32	 	{$rndping},[$key_],#16
+
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndpang
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndpang
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndpang
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndpang
+	aesmc		$dat5,$dat5
+	aese		$dat6,$rndpang
+	aesmc		$dat6,$dat6
+	aese		$dat7,$rndpang
+	aesmc		$dat7,$dat7
+	aese		$dat8,$rndpang
+	aesmc		$dat8,$dat8
+	aese		$dat9,$rndpang
+	aesmc		$dat9,$dat9
+	aese		$dat10,$rndpang
+	aesmc		$dat10,$dat10
+	aese		$dat11,$rndpang
+	aesmc		$dat11,$dat11
+	vld1.32	 	{$rndpang},[$key_],#16
+
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	 add		$tctr0,$ctr,#1
+	 add		$tctr1,$ctr,#2
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	 add		$tctr2,$ctr,#3
+	 add		$tctr3,$ctr,#4
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	 add		$tctr4,$ctr,#5
+	 add		$tctr5,$ctr,#6
+	 rev		$tctr0,$tctr0
+	aese		$dat3,$rndping
+	aesmc		$dat3,$dat3
+	 add		$tctr6,$ctr,#7
+	 add		$tctr7,$ctr,#8
+	 rev		$tctr1,$tctr1
+	 rev		$tctr2,$tctr2
+	aese		$dat4,$rndping
+	aesmc		$dat4,$dat4
+	 add		$tctr8,$ctr,#9
+	 add		$tctr9,$ctr,#10
+	 rev		$tctr3,$tctr3
+	 rev		$tctr4,$tctr4
+	aese		$dat5,$rndping
+	aesmc		$dat5,$dat5
+	 add		$tctr10,$ctr,#11
+	 add		$tctr11,$ctr,#12
+	 rev		$tctr5,$tctr5
+	 rev		$tctr6,$tctr6
+	aese		$dat6,$rndping
+	aesmc		$dat6,$dat6
+	 rev		$tctr7,$tctr7
+	 rev		$tctr8,$tctr8
+	aese		$dat7,$rndping
+	aesmc		$dat7,$dat7
+	 rev		$tctr9,$tctr9
+	 rev		$tctr10,$tctr10
+	aese		$dat8,$rndping
+	aesmc		$dat8,$dat8
+	 rev		$tctr11,$tctr11
+	aese		$dat9,$rndping
+	aesmc		$dat9,$dat9
+	aese		$dat10,$rndping
+	aesmc		$dat10,$dat10
+	aese		$dat11,$rndping
+	aesmc		$dat11,$dat11
+	vld1.32	 	{$rndping},[$key_],#16
+
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndpang
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndpang
+	aesmc		$dat3,$dat3
+	vld1.8		{$in0,$in1,$in2,$in3},[$inp],#64
+	aese		$dat4,$rndpang
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndpang
+	aesmc		$dat5,$dat5
+	aese		$dat6,$rndpang
+	aesmc		$dat6,$dat6
+	aese		$dat7,$rndpang
+	aesmc		$dat7,$dat7
+	vld1.8		{$in4,$in5,$in6,$in7},[$inp],#64
+	aese		$dat8,$rndpang
+	aesmc		$dat8,$dat8
+	aese		$dat9,$rndpang
+	aesmc		$dat9,$dat9
+	aese		$dat10,$rndpang
+	aesmc		$dat10,$dat10
+	aese		$dat11,$rndpang
+	aesmc		$dat11,$dat11
+	vld1.8		{$in8,$in9,$in10,$in11},[$inp],#64
+	vld1.32	 	{$rndpang},[$key_],#16
+
+	 mov		$key_, $key
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndping
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndping
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndping
+	aesmc		$dat5,$dat5
+	aese		$dat6,$rndping
+	aesmc		$dat6,$dat6
+	aese		$dat7,$rndping
+	aesmc		$dat7,$dat7
+	aese		$dat8,$rndping
+	aesmc		$dat8,$dat8
+	aese		$dat9,$rndping
+	aesmc		$dat9,$dat9
+	aese		$dat10,$rndping
+	aesmc		$dat10,$dat10
+	aese		$dat11,$rndping
+	aesmc		$dat11,$dat11
+	vld1.32	 	{$rndping},[$key_],#16	// re-pre-load rndkey[0]
+
+	aese		$dat0,$rndpang
+	 eor3		$in0,$in0,$rndlast,$dat0
+	vorr		$dat0,$ivec,$ivec
+	aese		$dat1,$rndpang
+	 eor3		$in1,$in1,$rndlast,$dat1
+	vorr		$dat1,$ivec,$ivec
+	aese		$dat2,$rndpang
+	 eor3		$in2,$in2,$rndlast,$dat2
+	vorr		$dat2,$ivec,$ivec
+	aese		$dat3,$rndpang
+	 eor3		$in3,$in3,$rndlast,$dat3
+	vorr		$dat3,$ivec,$ivec
+	aese		$dat4,$rndpang
+	 eor3		$in4,$in4,$rndlast,$dat4
+	vorr		$dat4,$ivec,$ivec
+	aese		$dat5,$rndpang
+	 eor3		$in5,$in5,$rndlast,$dat5
+	vorr		$dat5,$ivec,$ivec
+	aese		$dat6,$rndpang
+	 eor3		$in6,$in6,$rndlast,$dat6
+	vorr		$dat6,$ivec,$ivec
+	aese		$dat7,$rndpang
+	 eor3		$in7,$in7,$rndlast,$dat7
+	vorr		$dat7,$ivec,$ivec
+	aese		$dat8,$rndpang
+	 eor3		$in8,$in8,$rndlast,$dat8
+	vorr		$dat8,$ivec,$ivec
+	aese		$dat9,$rndpang
+	 eor3		$in9,$in9,$rndlast,$dat9
+	vorr		$dat9,$ivec,$ivec
+	aese		$dat10,$rndpang
+	 eor3		$in10,$in10,$rndlast,$dat10
+	vorr		$dat10,$ivec,$ivec
+	aese		$dat11,$rndpang
+	 eor3		$in11,$in11,$rndlast,$dat11
+	vorr		$dat11,$ivec,$ivec
+	vld1.32	 	{$rndpang},[$key_],#16	// re-pre-load rndkey[1]
+
+	vmov.32		${dat0}[3],$tctr0
+	vmov.32		${dat1}[3],$tctr1
+	vmov.32		${dat2}[3],$tctr2
+	vmov.32		${dat3}[3],$tctr3
+	vst1.8		{$in0,$in1,$in2,$in3},[$out],#64
+	vmov.32		${dat4}[3],$tctr4
+	vmov.32		${dat5}[3],$tctr5
+	vmov.32		${dat6}[3],$tctr6
+	vmov.32		${dat7}[3],$tctr7
+	vst1.8		{$in4,$in5,$in6,$in7},[$out],#64
+	vmov.32		${dat8}[3],$tctr8
+	vmov.32		${dat9}[3],$tctr9
+	vmov.32		${dat10}[3],$tctr10
+	vmov.32		${dat11}[3],$tctr11
+	vst1.8		{$in8,$in9,$in10,$in11},[$out],#64
+
+	 mov		$cnt,$rounds
+
+	 add		$ctr,$ctr,#12
+	subs		$len,$len,#12
+	b.hs		.Loop12x_ctr32_unroll
+
+	// pop regs from stack when 12 data chunks are interleaved
+	 ldp		$dat10d,$dat11d,[sp],#32
+	 ldp		$dat8d,$dat9d,[sp],#32
+	 ldp		x23,x24,[sp],#16
+	 ldp		x21,x22,[sp],#16
+	 ldp		x19,x20,[sp],#16
+
+	 add		$len,$len,#12
+	 cbz		$len,.Lctr32_done_unroll
+	 sub		$ctr,$ctr,#12
+
+	 cmp		$len,#2
+	b.ls		.Lctr32_tail_unroll
+
+	 cmp		$len,#6
+	 sub		$len,$len,#3		// bias
+	 add		$ctr,$ctr,#3
+	b.lo		.Loop3x_ctr32_unroll
+
+	 sub		$len,$len,#3
+	 add		$ctr,$ctr,#3
+	b.lo		.Loop6x_ctr32_unroll
+
+.align	4
+.Loop6x_ctr32_unroll:
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndping
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndping
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndping
+	aesmc		$dat5,$dat5
+	vld1.32		{$rndping},[$key_],#16
+	subs		$cnt,$cnt,#2
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndpang
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndpang
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndpang
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndpang
+	aesmc		$dat5,$dat5
+	vld1.32		{$rndpang},[$key_],#16
+	b.gt		.Loop6x_ctr32_unroll
+
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndping
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndping
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndping
+	aesmc		$dat5,$dat5
+	vld1.32	 	{$rndping},[$key_],#16
+
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndpang
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndpang
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndpang
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndpang
+	aesmc		$dat5,$dat5
+	vld1.32	 	{$rndpang},[$key_],#16
+
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	 add		$tctr0,$ctr,#1
+	 add		$tctr1,$ctr,#2
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	 add		$tctr2,$ctr,#3
+	 add		$tctr3,$ctr,#4
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	 add		$tctr4,$ctr,#5
+	 add		$tctr5,$ctr,#6
+	 rev		$tctr0,$tctr0
+	aese		$dat3,$rndping
+	aesmc		$dat3,$dat3
+	 rev		$tctr1,$tctr1
+	 rev		$tctr2,$tctr2
+	aese		$dat4,$rndping
+	aesmc		$dat4,$dat4
+	 rev		$tctr3,$tctr3
+	 rev		$tctr4,$tctr4
+	aese		$dat5,$rndping
+	aesmc		$dat5,$dat5
+	 rev		$tctr5,$tctr5
+	vld1.32	 	{$rndping},[$key_],#16
+
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	vld1.8		{$in0,$in1,$in2,$in3},[$inp],#64
+	aese		$dat2,$rndpang
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndpang
+	aesmc		$dat3,$dat3
+	vld1.8		{$in4,$in5},[$inp],#32
+	aese		$dat4,$rndpang
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndpang
+	aesmc		$dat5,$dat5
+	vld1.32	 	{$rndpang},[$key_],#16
+
+	 mov		$key_, $key
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	aese		$dat3,$rndping
+	aesmc		$dat3,$dat3
+	aese		$dat4,$rndping
+	aesmc		$dat4,$dat4
+	aese		$dat5,$rndping
+	aesmc		$dat5,$dat5
+	vld1.32	 	{$rndping},[$key_],#16	// re-pre-load rndkey[0]
+
+	aese		$dat0,$rndpang
+	 eor3		$in0,$in0,$rndlast,$dat0
+	aese		$dat1,$rndpang
+	 eor3		$in1,$in1,$rndlast,$dat1
+	aese		$dat2,$rndpang
+	 eor3		$in2,$in2,$rndlast,$dat2
+	aese		$dat3,$rndpang
+	 eor3		$in3,$in3,$rndlast,$dat3
+	aese		$dat4,$rndpang
+	 eor3		$in4,$in4,$rndlast,$dat4
+	aese		$dat5,$rndpang
+	 eor3		$in5,$in5,$rndlast,$dat5
+	vld1.32	 	{$rndpang},[$key_],#16	// re-pre-load rndkey[1]
+
+	vorr		$dat0,$ivec,$ivec
+	vorr		$dat1,$ivec,$ivec
+	vorr		$dat2,$ivec,$ivec
+	vorr		$dat3,$ivec,$ivec
+	vorr		$dat4,$ivec,$ivec
+	vorr		$dat5,$ivec,$ivec
+
+	vmov.32		${dat0}[3],$tctr0
+	vmov.32		${dat1}[3],$tctr1
+	vst1.8		{$in0,$in1,$in2,$in3},[$out],#64
+	vmov.32		${dat2}[3],$tctr2
+	vmov.32		${dat3}[3],$tctr3
+	vst1.8		{$in4,$in5},[$out],#32
+	vmov.32		${dat4}[3],$tctr4
+	vmov.32		${dat5}[3],$tctr5
+
+	 cbz		$len,.Lctr32_done_unroll
+	 mov		$cnt,$rounds
+
+	 cmp		$len,#2
+	b.ls		.Lctr32_tail_unroll
+
+	 sub		$len,$len,#3		// bias
+	 add		$ctr,$ctr,#3
+	 b		.Loop3x_ctr32_unroll
+
+.align	4
+.Loop3x_ctr32_unroll:
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	vld1.32		{$rndping},[$key_],#16
+	subs		$cnt,$cnt,#2
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	aese		$dat2,$rndpang
+	aesmc		$dat2,$dat2
+	vld1.32		{$rndpang},[$key_],#16
+	b.gt		.Loop3x_ctr32_unroll
+
+	aese		$dat0,$rndping
+	aesmc		$tmp0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$tmp1,$dat1
+	vld1.8		{$in0,$in1,$in2},[$inp],#48
+	vorr		$dat0,$ivec,$ivec
+	aese		$dat2,$rndping
+	aesmc		$dat2,$dat2
+	vld1.32		{$rndping},[$key_],#16
+	vorr		$dat1,$ivec,$ivec
+	aese		$tmp0,$rndpang
+	aesmc		$tmp0,$tmp0
+	aese		$tmp1,$rndpang
+	aesmc		$tmp1,$tmp1
+	aese		$dat2,$rndpang
+	aesmc		$tmp2,$dat2
+	vld1.32		{$rndpang},[$key_],#16
+	vorr		$dat2,$ivec,$ivec
+	 add		$tctr0,$ctr,#1
+	aese		$tmp0,$rndping
+	aesmc		$tmp0,$tmp0
+	aese		$tmp1,$rndping
+	aesmc		$tmp1,$tmp1
+	 add		$tctr1,$ctr,#2
+	aese		$tmp2,$rndping
+	aesmc		$tmp2,$tmp2
+	vld1.32		{$rndping},[$key_],#16
+	 add		$ctr,$ctr,#3
+	aese		$tmp0,$rndpang
+	aesmc		$tmp0,$tmp0
+	aese		$tmp1,$rndpang
+	aesmc		$tmp1,$tmp1
+
+	 rev		$tctr0,$tctr0
+	aese		$tmp2,$rndpang
+	aesmc		$tmp2,$tmp2
+	vld1.32		{$rndpang},[$key_],#16
+	vmov.32		${dat0}[3], $tctr0
+	 mov		$key_,$key
+	 rev		$tctr1,$tctr1
+	aese		$tmp0,$rndping
+	aesmc		$tmp0,$tmp0
+
+	aese		$tmp1,$rndping
+	aesmc		$tmp1,$tmp1
+	vmov.32		${dat1}[3], $tctr1
+	 rev		$tctr2,$ctr
+	aese		$tmp2,$rndping
+	aesmc		$tmp2,$tmp2
+	vmov.32		${dat2}[3], $tctr2
+
+	aese		$tmp0,$rndpang
+	aese		$tmp1,$rndpang
+	aese		$tmp2,$rndpang
+
+	 eor3		$in0,$in0,$rndlast,$tmp0
+	vld1.32		{$rndping},[$key_],#16	// re-pre-load rndkey[0]
+	 eor3		$in1,$in1,$rndlast,$tmp1
+	 mov		$cnt,$rounds
+	 eor3		$in2,$in2,$rndlast,$tmp2
+	vld1.32		{$rndpang},[$key_],#16	// re-pre-load rndkey[1]
+	vst1.8		{$in0,$in1,$in2},[$out],#48
+
+	 cbz		$len,.Lctr32_done_unroll
+
+.Lctr32_tail_unroll:
+	 cmp		$len,#1
+	b.eq		.Lctr32_tail_1_unroll
+
+.Lctr32_tail_2_unroll:
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	vld1.32		{$rndping},[$key_],#16
+	subs		$cnt,$cnt,#2
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	vld1.32		{$rndpang},[$key_],#16
+	b.gt		.Lctr32_tail_2_unroll
+
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	vld1.32		{$rndping},[$key_],#16
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	vld1.32		{$rndpang},[$key_],#16
+	vld1.8		{$in0,$in1},[$inp],#32
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	vld1.32		{$rndping},[$key_],#16
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndpang
+	aesmc		$dat1,$dat1
+	vld1.32		{$rndpang},[$key_],#16
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat1,$rndping
+	aesmc		$dat1,$dat1
+	aese		$dat0,$rndpang
+	aese		$dat1,$rndpang
+
+	 eor3		$in0,$in0,$rndlast,$dat0
+	 eor3		$in1,$in1,$rndlast,$dat1
+	vst1.8		{$in0,$in1},[$out],#32
+	 b		.Lctr32_done_unroll
+
+.Lctr32_tail_1_unroll:
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	vld1.32		{$rndping},[$key_],#16
+	subs		$cnt,$cnt,#2
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	vld1.32		{$rndpang},[$key_],#16
+	b.gt		.Lctr32_tail_1_unroll
+
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	vld1.32		{$rndping},[$key_],#16
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	vld1.32		{$rndpang},[$key_],#16
+	vld1.8		{$in0},[$inp]
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	vld1.32		{$rndping},[$key_],#16
+	aese		$dat0,$rndpang
+	aesmc		$dat0,$dat0
+	vld1.32		{$rndpang},[$key_],#16
+	aese		$dat0,$rndping
+	aesmc		$dat0,$dat0
+	aese		$dat0,$rndpang
+
+	 eor3		$in0,$in0,$rndlast,$dat0
+	vst1.8		{$in0},[$out],#16
+
+.Lctr32_done_unroll:
+	ldp		d8,d9,[sp, #16]
+	ldp		d10,d11,[sp, #32]
+	ldp		d12,d13,[sp, #48]
+	ldp		d15,d16,[sp, #64]
+	ldr		x29,[sp],#80
+	ret
+.size	${prefix}_ctr32_encrypt_blocks_unroll12_eor3,.-${prefix}_ctr32_encrypt_blocks_unroll12_eor3
+___
+}}}
+
 {{{
 {{{
 my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4));
 my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4));
 my ($rounds,$cnt,$key_)=("w5","w6","x7");
 my ($rounds,$cnt,$key_)=("w5","w6","x7");
@@ -3640,7 +4389,8 @@ ___
 if ($flavour =~ /64/) {			######## 64-bit code
 if ($flavour =~ /64/) {			######## 64-bit code
     my %opcode = (
     my %opcode = (
 	"aesd"	=>	0x4e285800,	"aese"	=>	0x4e284800,
 	"aesd"	=>	0x4e285800,	"aese"	=>	0x4e284800,
-	"aesimc"=>	0x4e287800,	"aesmc"	=>	0x4e286800	);
+	"aesimc"=>	0x4e287800,	"aesmc"	=>	0x4e286800,
+	"eor3"	=>	0xce000000,	);
 
 
     local *unaes = sub {
     local *unaes = sub {
 	my ($mnemonic,$arg)=@_;
 	my ($mnemonic,$arg)=@_;
@@ -3651,10 +4401,21 @@ if ($flavour =~ /64/) {			######## 64-bit code
 			$mnemonic,$arg;
 			$mnemonic,$arg;
     };
     };
 
 
+    sub unsha3 {
+		 my ($mnemonic,$arg)=@_;
+
+		 $arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv#]([0-9\-]+))?)?/
+		 &&
+		 sprintf ".inst\t0x%08x\t//%s %s",
+			$opcode{$mnemonic}|$1|($2<<5)|($3<<16)|(eval($4)<<10),
+			$mnemonic,$arg;
+    }
+
     foreach(split("\n",$code)) {
     foreach(split("\n",$code)) {
 	s/\`([^\`]*)\`/eval($1)/geo;
 	s/\`([^\`]*)\`/eval($1)/geo;
 
 
-	s/\bq([0-9]+)\b/"v".($1<8?$1:$1+8).".16b"/geo;	# old->new registers
+	s/\bq([0-9]+)\b/"v".($1<8?$1:($1<24?$1+8:$1-16)).".16b"/geo;	# old->new registers
+	s/\bq_([0-9]+)\b/"q".$1/geo;	# old->new registers
 	s/@\s/\/\//o;			# old->new style commentary
 	s/@\s/\/\//o;			# old->new style commentary
 
 
 	#s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo	or
 	#s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo	or
@@ -3667,6 +4428,7 @@ if ($flavour =~ /64/) {			######## 64-bit code
 	s/vshr/ushr/o		or
 	s/vshr/ushr/o		or
 	s/^(\s+)v/$1/o		or	# strip off v prefix
 	s/^(\s+)v/$1/o		or	# strip off v prefix
 	s/\bbx\s+lr\b/ret/o;
 	s/\bbx\s+lr\b/ret/o;
+	s/\b(eor3)\s+(v.*)/unsha3($1,$2)/ge;
 
 
 	# fix up remaining legacy suffixes
 	# fix up remaining legacy suffixes
 	s/\.[ui]?8//o;
 	s/\.[ui]?8//o;

+ 4 - 1
libs/openssl/crypto/aes/build.info

@@ -51,7 +51,7 @@ IF[{- !$disabled{asm} -}]
   # aes-c64xplus.s implements AES_ctr32_encrypt
   # aes-c64xplus.s implements AES_ctr32_encrypt
   $AESDEF_c64xplus=AES_ASM AES_CTR_ASM
   $AESDEF_c64xplus=AES_ASM AES_CTR_ASM
 
 
-  $AESASM_riscv64=aes_cbc.c aes-riscv64.s aes-riscv64-zkn.s
+  $AESASM_riscv64=aes_cbc.c aes-riscv64.s aes-riscv64-zkn.s aes-riscv64-zvkb-zvkned.s aes-riscv64-zvkned.s aes-riscv64-zvbb-zvkg-zvkned.s
   $AESDEF_riscv64=AES_ASM
   $AESDEF_riscv64=AES_ASM
   $AESASM_riscv32=aes_core.c aes_cbc.c aes-riscv32-zkn.s
   $AESASM_riscv32=aes_core.c aes_cbc.c aes-riscv32-zkn.s
 
 
@@ -128,6 +128,9 @@ INCLUDE[aes-mips.o]=..
 GENERATE[aes-riscv64.s]=asm/aes-riscv64.pl
 GENERATE[aes-riscv64.s]=asm/aes-riscv64.pl
 GENERATE[aes-riscv64-zkn.s]=asm/aes-riscv64-zkn.pl
 GENERATE[aes-riscv64-zkn.s]=asm/aes-riscv64-zkn.pl
 GENERATE[aes-riscv32-zkn.s]=asm/aes-riscv32-zkn.pl
 GENERATE[aes-riscv32-zkn.s]=asm/aes-riscv32-zkn.pl
+GENERATE[aes-riscv64-zvkb-zvkned.s]=asm/aes-riscv64-zvkb-zvkned.pl
+GENERATE[aes-riscv64-zvkned.s]=asm/aes-riscv64-zvkned.pl
+GENERATE[aes-riscv64-zvbb-zvkg-zvkned.s]=asm/aes-riscv64-zvbb-zvkg-zvkned.pl
 
 
 GENERATE[aesv8-armx.S]=asm/aesv8-armx.pl
 GENERATE[aesv8-armx.S]=asm/aesv8-armx.pl
 INCLUDE[aesv8-armx.o]=..
 INCLUDE[aesv8-armx.o]=..

+ 5 - 1
libs/openssl/crypto/arm_arch.h

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2011-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2011-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -88,6 +88,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized;
 # define ARMV8_SVE       (1<<13)
 # define ARMV8_SVE       (1<<13)
 # define ARMV8_SVE2      (1<<14)
 # define ARMV8_SVE2      (1<<14)
 # define ARMV8_HAVE_SHA3_AND_WORTH_USING     (1<<15)
 # define ARMV8_HAVE_SHA3_AND_WORTH_USING     (1<<15)
+# define ARMV8_UNROLL12_EOR3     (1<<16)
 
 
 /*
 /*
  * MIDR_EL1 system register
  * MIDR_EL1 system register
@@ -102,6 +103,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized;
 # define ARM_CPU_IMP_ARM           0x41
 # define ARM_CPU_IMP_ARM           0x41
 # define HISI_CPU_IMP              0x48
 # define HISI_CPU_IMP              0x48
 # define ARM_CPU_IMP_APPLE         0x61
 # define ARM_CPU_IMP_APPLE         0x61
+# define ARM_CPU_IMP_MICROSOFT     0x6D
 
 
 # define ARM_CPU_PART_CORTEX_A72   0xD08
 # define ARM_CPU_PART_CORTEX_A72   0xD08
 # define ARM_CPU_PART_N1           0xD0C
 # define ARM_CPU_PART_N1           0xD0C
@@ -123,6 +125,8 @@ extern unsigned int OPENSSL_armv8_rsa_neonized;
 # define APPLE_CPU_PART_M2_BLIZZARD_MAX     0x038
 # define APPLE_CPU_PART_M2_BLIZZARD_MAX     0x038
 # define APPLE_CPU_PART_M2_AVALANCHE_MAX    0x039
 # define APPLE_CPU_PART_M2_AVALANCHE_MAX    0x039
 
 
+# define MICROSOFT_CPU_PART_COBALT_100      0xD49
+
 # define MIDR_PARTNUM_SHIFT       4
 # define MIDR_PARTNUM_SHIFT       4
 # define MIDR_PARTNUM_MASK        (0xfffU << MIDR_PARTNUM_SHIFT)
 # define MIDR_PARTNUM_MASK        (0xfffU << MIDR_PARTNUM_SHIFT)
 # define MIDR_PARTNUM(midr)       \
 # define MIDR_PARTNUM(midr)       \

+ 8 - 2
libs/openssl/crypto/armcap.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2011-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2011-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -298,7 +298,8 @@ void OPENSSL_cpuid_setup(void)
             size_t len = sizeof(uarch);
             size_t len = sizeof(uarch);
             if ((sysctlbyname("machdep.cpu.brand_string", uarch, &len, NULL, 0) == 0) &&
             if ((sysctlbyname("machdep.cpu.brand_string", uarch, &len, NULL, 0) == 0) &&
                ((strncmp(uarch, "Apple M1", 8) == 0) ||
                ((strncmp(uarch, "Apple M1", 8) == 0) ||
-                (strncmp(uarch, "Apple M2", 8) == 0))) {
+                (strncmp(uarch, "Apple M2", 8) == 0) ||
+                (strncmp(uarch, "Apple M3", 8) == 0))) {
                 OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3;
                 OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3;
                 OPENSSL_armcap_P |= ARMV8_HAVE_SHA3_AND_WORTH_USING;
                 OPENSSL_armcap_P |= ARMV8_HAVE_SHA3_AND_WORTH_USING;
             }
             }
@@ -417,9 +418,14 @@ void OPENSSL_cpuid_setup(void)
     }
     }
     if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) ||
     if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) ||
          MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N2) ||
          MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N2) ||
+         MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_COBALT_100) ||
          MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)) &&
          MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)) &&
         (OPENSSL_armcap_P & ARMV8_SHA3))
         (OPENSSL_armcap_P & ARMV8_SHA3))
         OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3;
         OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3;
+    if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) ||
+         MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)) &&
+        (OPENSSL_armcap_P & ARMV8_SHA3))
+        OPENSSL_armcap_P |= ARMV8_UNROLL12_EOR3;
     if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)     ||
     if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)     ||
          MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)      ||
          MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)      ||
          MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) ||
          MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) ||

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

@@ -79,7 +79,7 @@ int ossl_asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d)
     static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
     static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
     static const int mdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
     static const int mdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
     char *a;
     char *a;
-    int n, i, i2, l, o, min_l = 11, strict = 0, end = 6, btz = 5, md;
+    int n, i, i2, l, o, min_l, strict = 0, end = 6, btz = 5, md;
     struct tm tmp;
     struct tm tmp;
 #if defined(CHARSET_EBCDIC)
 #if defined(CHARSET_EBCDIC)
     const char upper_z = 0x5A, num_zero = 0x30, period = 0x2E, minus = 0x2D, plus = 0x2B;
     const char upper_z = 0x5A, num_zero = 0x30, period = 0x2E, minus = 0x2D, plus = 0x2B;
@@ -95,18 +95,16 @@ int ossl_asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d)
      * 3. "+|-" is not allowed to indicate a timezone
      * 3. "+|-" is not allowed to indicate a timezone
      */
      */
     if (d->type == V_ASN1_UTCTIME) {
     if (d->type == V_ASN1_UTCTIME) {
+        min_l = 13;
         if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
         if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
-            min_l = 13;
             strict = 1;
             strict = 1;
         }
         }
     } else if (d->type == V_ASN1_GENERALIZEDTIME) {
     } else if (d->type == V_ASN1_GENERALIZEDTIME) {
         end = 7;
         end = 7;
         btz = 6;
         btz = 6;
+        min_l = 15;
         if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
         if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
-            min_l = 15;
             strict = 1;
             strict = 1;
-        } else {
-            min_l = 13;
         }
         }
     } else {
     } else {
         return 0;
         return 0;

+ 5 - 1
libs/openssl/crypto/asn1/asn1_err.c

@@ -1,6 +1,6 @@
 /*
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -55,6 +55,8 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = {
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIELD_MISSING), "field missing"},
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIELD_MISSING), "field missing"},
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIRST_NUM_TOO_LARGE),
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIRST_NUM_TOO_LARGE),
     "first num too large"},
     "first num too large"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_GENERALIZEDTIME_IS_TOO_SHORT),
+    "generalizedtime is too short"},
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_HEADER_TOO_LONG), "header too long"},
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_HEADER_TOO_LONG), "header too long"},
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_BITSTRING_FORMAT),
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_BITSTRING_FORMAT),
     "illegal bitstring format"},
     "illegal bitstring format"},
@@ -192,6 +194,8 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = {
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),
     "unsupported public key type"},
     "unsupported public key type"},
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_TYPE), "unsupported type"},
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_TYPE), "unsupported type"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UTCTIME_IS_TOO_SHORT),
+    "utctime is too short"},
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_INTEGER_TYPE),
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_INTEGER_TYPE),
     "wrong integer type"},
     "wrong integer type"},
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_PUBLIC_KEY_TYPE),
     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_PUBLIC_KEY_TYPE),

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -921,6 +921,14 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
             ERR_raise(ERR_LIB_ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
             ERR_raise(ERR_LIB_ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
             goto err;
             goto err;
         }
         }
+        if (utype == V_ASN1_GENERALIZEDTIME && (len < 15)) {
+            ERR_raise(ERR_LIB_ASN1, ASN1_R_GENERALIZEDTIME_IS_TOO_SHORT);
+            goto err;
+        }
+        if (utype == V_ASN1_UTCTIME && (len < 13)) {
+            ERR_raise(ERR_LIB_ASN1, ASN1_R_UTCTIME_IS_TOO_SHORT);
+            goto err;
+        }
         /* All based on ASN1_STRING and handled the same */
         /* All based on ASN1_STRING and handled the same */
         if (*pval == NULL) {
         if (*pval == NULL) {
             stmp = ASN1_STRING_type_new(utype);
             stmp = ASN1_STRING_type_new(utype);

+ 3 - 2
libs/openssl/crypto/bio/bio_dump.c

@@ -141,9 +141,10 @@ int BIO_hex_string(BIO *out, int indent, int width, const void *data,
 
 
         BIO_printf(out, "%02X:", d[i]);
         BIO_printf(out, "%02X:", d[i]);
 
 
-        j = (j + 1) % width;
-        if (!j)
+        if (++j >= width) {
+            j = 0;
             BIO_printf(out, "\n");
             BIO_printf(out, "\n");
+        }
     }
     }
 
 
     if (i && !j)
     if (i && !j)

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

@@ -817,7 +817,7 @@ BIO *BIO_find_type(BIO *bio, int type)
         ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
         ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
         return NULL;
         return NULL;
     }
     }
-    mask = type & 0xff;
+    mask = type & BIO_TYPE_MASK;
     do {
     do {
         if (bio->method != NULL) {
         if (bio->method != NULL) {
             mt = bio->method->type;
             mt = bio->method->type;

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -29,6 +29,8 @@ int BIO_get_new_index(void)
     }
     }
     if (!CRYPTO_UP_REF(&bio_type_count, &newval))
     if (!CRYPTO_UP_REF(&bio_type_count, &newval))
         return -1;
         return -1;
+    if (newval > BIO_TYPE_MASK)
+        return -1;
     return newval;
     return newval;
 }
 }
 
 

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

@@ -26,9 +26,6 @@ static int wsa_init_done = 0;
 # if defined __TANDEM
 # if defined __TANDEM
 #  include <unistd.h>
 #  include <unistd.h>
 #  include <sys/time.h> /* select */
 #  include <sys/time.h> /* select */
-#  if defined(OPENSSL_TANDEM_FLOSS)
-#   include <floss.h(floss_select)>
-#  endif
 # elif defined _WIN32
 # elif defined _WIN32
 #  include <winsock.h> /* for type fd_set */
 #  include <winsock.h> /* for type fd_set */
 # else
 # else

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

@@ -107,7 +107,7 @@
     || M_METHOD == M_METHOD_WSARECVMSG
     || M_METHOD == M_METHOD_WSARECVMSG
 #  if defined(__APPLE__)
 #  if defined(__APPLE__)
     /*
     /*
-     * CMSG_SPACE is not a constant expresson on OSX even though POSIX
+     * CMSG_SPACE is not a constant expression on OSX even though POSIX
      * says it's supposed to be. This should be adequate.
      * says it's supposed to be. This should be adequate.
      */
      */
 #   define BIO_CMSG_ALLOC_LEN   64
 #   define BIO_CMSG_ALLOC_LEN   64

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy

+ 476 - 0
libs/openssl/crypto/chacha/asm/chacha-riscv64-zbb-zvkb.pl

@@ -0,0 +1,476 @@
+#! /usr/bin/env perl
+# This file is dual-licensed, meaning that you can use it under your
+# choice of either of the following two licenses:
+#
+# Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+# or
+#
+# Copyright (c) 2023, Jerry Shih <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# - RV64I
+# - RISC-V Vector ('V') with VLEN >= 128
+# - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb')
+# - RISC-V Basic Bit-manipulation extension ('Zbb')
+# - RISC-V Zicclsm(Main memory supports misaligned loads/stores)
+
+use strict;
+use warnings;
+
+use FindBin qw($Bin);
+use lib "$Bin";
+use lib "$Bin/../../perlasm";
+use riscv;
+
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+my $output  = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop   : undef;
+my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.|          ? shift : undef;
+
+$output and open STDOUT, ">$output";
+
+my $code = <<___;
+.text
+___
+
+# void ChaCha20_ctr32_zbb_zvkb(unsigned char *out, const unsigned char *inp,
+#                              size_t len, const unsigned int key[8],
+#                              const unsigned int counter[4]);
+################################################################################
+my ( $OUTPUT, $INPUT, $LEN, $KEY, $COUNTER ) = ( "a0", "a1", "a2", "a3", "a4" );
+my ( $CONST_DATA0, $CONST_DATA1, $CONST_DATA2, $CONST_DATA3 ) = ( "a5", "a6",
+  "a7", "s0" );
+my ( $KEY0, $KEY1, $KEY2, $KEY3, $KEY4, $KEY5, $KEY6, $KEY7, $COUNTER0,
+     $COUNTER1, $NONCE0, $NONCE1) = ( "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+  "s8", "s9", "s10", "s11", "t0" );
+my ( $STATE0, $STATE1, $STATE2, $STATE3,
+     $STATE4, $STATE5, $STATE6, $STATE7,
+     $STATE8, $STATE9, $STATE10, $STATE11,
+     $STATE12, $STATE13, $STATE14, $STATE15) = (
+     $CONST_DATA0, $CONST_DATA1, $CONST_DATA2, $CONST_DATA3,
+     $KEY0, $KEY1, $KEY2, $KEY3,
+     $KEY4, $KEY5, $KEY6, $KEY7,
+     $COUNTER0, $COUNTER1, $NONCE0, $NONCE1 );
+my ( $VL ) = ( "t1" );
+my ( $CURRENT_COUNTER ) = ( "t2" );
+my ( $T0 ) = ( "t3" );
+my ( $T1 ) = ( "t4" );
+my ( $T2 ) = ( "t5" );
+my ( $T3 ) = ( "t6" );
+my (
+    $V0,  $V1,  $V2,  $V3,  $V4,  $V5,  $V6,  $V7,  $V8,  $V9,  $V10,
+    $V11, $V12, $V13, $V14, $V15, $V16, $V17, $V18, $V19, $V20, $V21,
+    $V22, $V23, $V24, $V25, $V26, $V27, $V28, $V29, $V30, $V31,
+) = map( "v$_", ( 0 .. 31 ) );
+
+sub chacha_quad_round_group {
+    my (
+        $A0, $B0, $C0, $D0,
+        $A1, $B1, $C1, $D1,
+        $A2, $B2, $C2, $D2,
+        $A3, $B3, $C3, $D3,
+
+        $S_A0, $S_B0, $S_C0, $S_D0,
+        $S_A1, $S_B1, $S_C1, $S_D1,
+        $S_A2, $S_B2, $S_C2, $S_D2,
+        $S_A3, $S_B3, $S_C3, $S_D3,
+    ) = @_;
+
+    my $code = <<___;
+    # a += b; d ^= a; d <<<= 16;
+    @{[vadd_vv $A0, $A0, $B0]}
+    add $S_A0, $S_A0, $S_B0
+    @{[vadd_vv $A1, $A1, $B1]}
+    add $S_A1, $S_A1, $S_B1
+    @{[vadd_vv $A2, $A2, $B2]}
+    add $S_A2, $S_A2, $S_B2
+    @{[vadd_vv $A3, $A3, $B3]}
+    add $S_A3, $S_A3, $S_B3
+    @{[vxor_vv $D0, $D0, $A0]}
+    xor $S_D0, $S_D0, $S_A0
+    @{[vxor_vv $D1, $D1, $A1]}
+    xor $S_D1, $S_D1, $S_A1
+    @{[vxor_vv $D2, $D2, $A2]}
+    xor $S_D2, $S_D2, $S_A2
+    @{[vxor_vv $D3, $D3, $A3]}
+    xor $S_D3, $S_D3, $S_A3
+    @{[vror_vi $D0, $D0, 32 - 16]}
+    @{[roriw $S_D0, $S_D0, 32 - 16]}
+    @{[vror_vi $D1, $D1, 32 - 16]}
+    @{[roriw $S_D1, $S_D1, 32 - 16]}
+    @{[vror_vi $D2, $D2, 32 - 16]}
+    @{[roriw $S_D2, $S_D2, 32 - 16]}
+    @{[vror_vi $D3, $D3, 32 - 16]}
+    @{[roriw $S_D3, $S_D3, 32 - 16]}
+    # c += d; b ^= c; b <<<= 12;
+    @{[vadd_vv $C0, $C0, $D0]}
+    add $S_C0, $S_C0, $S_D0
+    @{[vadd_vv $C1, $C1, $D1]}
+    add $S_C1, $S_C1, $S_D1
+    @{[vadd_vv $C2, $C2, $D2]}
+    add $S_C2, $S_C2, $S_D2
+    @{[vadd_vv $C3, $C3, $D3]}
+    add $S_C3, $S_C3, $S_D3
+    @{[vxor_vv $B0, $B0, $C0]}
+    xor $S_B0, $S_B0, $S_C0
+    @{[vxor_vv $B1, $B1, $C1]}
+    xor $S_B1, $S_B1, $S_C1
+    @{[vxor_vv $B2, $B2, $C2]}
+    xor $S_B2, $S_B2, $S_C2
+    @{[vxor_vv $B3, $B3, $C3]}
+    xor $S_B3, $S_B3, $S_C3
+    @{[vror_vi $B0, $B0, 32 - 12]}
+    @{[roriw $S_B0, $S_B0, 32 - 12]}
+    @{[vror_vi $B1, $B1, 32 - 12]}
+    @{[roriw $S_B1, $S_B1, 32 - 12]}
+    @{[vror_vi $B2, $B2, 32 - 12]}
+    @{[roriw $S_B2, $S_B2, 32 - 12]}
+    @{[vror_vi $B3, $B3, 32 - 12]}
+    @{[roriw $S_B3, $S_B3, 32 - 12]}
+    # a += b; d ^= a; d <<<= 8;
+    @{[vadd_vv $A0, $A0, $B0]}
+    add $S_A0, $S_A0, $S_B0
+    @{[vadd_vv $A1, $A1, $B1]}
+    add $S_A1, $S_A1, $S_B1
+    @{[vadd_vv $A2, $A2, $B2]}
+    add $S_A2, $S_A2, $S_B2
+    @{[vadd_vv $A3, $A3, $B3]}
+    add $S_A3, $S_A3, $S_B3
+    @{[vxor_vv $D0, $D0, $A0]}
+    xor $S_D0, $S_D0, $S_A0
+    @{[vxor_vv $D1, $D1, $A1]}
+    xor $S_D1, $S_D1, $S_A1
+    @{[vxor_vv $D2, $D2, $A2]}
+    xor $S_D2, $S_D2, $S_A2
+    @{[vxor_vv $D3, $D3, $A3]}
+    xor $S_D3, $S_D3, $S_A3
+    @{[vror_vi $D0, $D0, 32 - 8]}
+    @{[roriw $S_D0, $S_D0, 32 - 8]}
+    @{[vror_vi $D1, $D1, 32 - 8]}
+    @{[roriw $S_D1, $S_D1, 32 - 8]}
+    @{[vror_vi $D2, $D2, 32 - 8]}
+    @{[roriw $S_D2, $S_D2, 32 - 8]}
+    @{[vror_vi $D3, $D3, 32 - 8]}
+    @{[roriw $S_D3, $S_D3, 32 - 8]}
+    # c += d; b ^= c; b <<<= 7;
+    @{[vadd_vv $C0, $C0, $D0]}
+    add $S_C0, $S_C0, $S_D0
+    @{[vadd_vv $C1, $C1, $D1]}
+    add $S_C1, $S_C1, $S_D1
+    @{[vadd_vv $C2, $C2, $D2]}
+    add $S_C2, $S_C2, $S_D2
+    @{[vadd_vv $C3, $C3, $D3]}
+    add $S_C3, $S_C3, $S_D3
+    @{[vxor_vv $B0, $B0, $C0]}
+    xor $S_B0, $S_B0, $S_C0
+    @{[vxor_vv $B1, $B1, $C1]}
+    xor $S_B1, $S_B1, $S_C1
+    @{[vxor_vv $B2, $B2, $C2]}
+    xor $S_B2, $S_B2, $S_C2
+    @{[vxor_vv $B3, $B3, $C3]}
+    xor $S_B3, $S_B3, $S_C3
+    @{[vror_vi $B0, $B0, 32 - 7]}
+    @{[roriw $S_B0, $S_B0, 32 - 7]}
+    @{[vror_vi $B1, $B1, 32 - 7]}
+    @{[roriw $S_B1, $S_B1, 32 - 7]}
+    @{[vror_vi $B2, $B2, 32 - 7]}
+    @{[roriw $S_B2, $S_B2, 32 - 7]}
+    @{[vror_vi $B3, $B3, 32 - 7]}
+    @{[roriw $S_B3, $S_B3, 32 - 7]}
+___
+
+    return $code;
+}
+
+$code .= <<___;
+.p2align 3
+.globl ChaCha20_ctr32_zbb_zvkb
+.type ChaCha20_ctr32_zbb_zvkb,\@function
+ChaCha20_ctr32_zbb_zvkb:
+    addi sp, sp, -96
+    sd s0, 0(sp)
+    sd s1, 8(sp)
+    sd s2, 16(sp)
+    sd s3, 24(sp)
+    sd s4, 32(sp)
+    sd s5, 40(sp)
+    sd s6, 48(sp)
+    sd s7, 56(sp)
+    sd s8, 64(sp)
+    sd s9, 72(sp)
+    sd s10, 80(sp)
+    sd s11, 88(sp)
+    addi sp, sp, -64
+
+    lw $CURRENT_COUNTER, 0($COUNTER)
+
+.Lblock_loop:
+    # We will use the scalar ALU for 1 chacha block.
+    srli $T0, $LEN, 6
+    @{[vsetvli $VL, $T0, "e32", "m1", "ta", "ma"]}
+    slli $T1, $VL, 6
+    bltu $T1, $LEN, 1f
+    # Since there is no more chacha block existed, we need to split 1 block
+    # from vector ALU.
+    addi $T1, $VL, -1
+    @{[vsetvli $VL, $T1, "e32", "m1", "ta", "ma"]}
+1:
+
+    #### chacha block data
+    # init chacha const states
+    # "expa" little endian
+    li $CONST_DATA0, 0x61707865
+    @{[vmv_v_x $V0, $CONST_DATA0]}
+    # "nd 3" little endian
+    li $CONST_DATA1, 0x3320646e
+    @{[vmv_v_x $V1, $CONST_DATA1]}
+    # "2-by" little endian
+    li $CONST_DATA2, 0x79622d32
+    @{[vmv_v_x $V2, $CONST_DATA2]}
+    # "te k" little endian
+    li $CONST_DATA3, 0x6b206574
+    lw $KEY0, 0($KEY)
+    @{[vmv_v_x $V3, $CONST_DATA3]}
+
+    # init chacha key states
+    lw $KEY1, 4($KEY)
+    @{[vmv_v_x $V4, $KEY0]}
+    lw $KEY2, 8($KEY)
+    @{[vmv_v_x $V5, $KEY1]}
+    lw $KEY3, 12($KEY)
+    @{[vmv_v_x $V6, $KEY2]}
+    lw $KEY4, 16($KEY)
+    @{[vmv_v_x $V7, $KEY3]}
+    lw $KEY5, 20($KEY)
+    @{[vmv_v_x $V8, $KEY4]}
+    lw $KEY6, 24($KEY)
+    @{[vmv_v_x $V9, $KEY5]}
+    lw $KEY7, 28($KEY)
+    @{[vmv_v_x $V10, $KEY6]}
+    @{[vmv_v_x $V11, $KEY7]}
+
+    # init chacha key states
+    lw $COUNTER1, 4($COUNTER)
+    @{[vid_v $V12]}
+    lw $NONCE0, 8($COUNTER)
+    @{[vadd_vx $V12, $V12, $CURRENT_COUNTER]}
+    lw $NONCE1, 12($COUNTER)
+    @{[vmv_v_x $V13, $COUNTER1]}
+    add $COUNTER0, $CURRENT_COUNTER, $VL
+
+    # init chacha nonce states
+    @{[vmv_v_x $V14, $NONCE0]}
+    @{[vmv_v_x $V15, $NONCE1]}
+
+    li $T0, 64
+    # load the top-half of input data
+    @{[vlsseg_nf_e32_v 8, $V16, $INPUT, $T0]}
+
+    # 20 round groups
+    li $T0, 10
+.Lround_loop:
+    addi $T0, $T0, -1
+    @{[chacha_quad_round_group
+      $V0, $V4, $V8, $V12,
+      $V1, $V5, $V9, $V13,
+      $V2, $V6, $V10, $V14,
+      $V3, $V7, $V11, $V15,
+      $STATE0, $STATE4, $STATE8, $STATE12,
+      $STATE1, $STATE5, $STATE9, $STATE13,
+      $STATE2, $STATE6, $STATE10, $STATE14,
+      $STATE3, $STATE7, $STATE11, $STATE15]}
+    @{[chacha_quad_round_group
+      $V3, $V4, $V9, $V14,
+      $V0, $V5, $V10, $V15,
+      $V1, $V6, $V11, $V12,
+      $V2, $V7, $V8, $V13,
+      $STATE3, $STATE4, $STATE9, $STATE14,
+      $STATE0, $STATE5, $STATE10, $STATE15,
+      $STATE1, $STATE6, $STATE11, $STATE12,
+      $STATE2, $STATE7, $STATE8, $STATE13]}
+    bnez $T0, .Lround_loop
+
+    li $T0, 64
+    # load the bottom-half of input data
+    addi $T1, $INPUT, 32
+    @{[vlsseg_nf_e32_v 8, $V24, $T1, $T0]}
+
+    # add chacha top-half initial block states
+    # "expa" little endian
+    li $T0, 0x61707865
+    @{[vadd_vx $V0, $V0, $T0]}
+    add $STATE0, $STATE0, $T0
+    # "nd 3" little endian
+    li $T1, 0x3320646e
+    @{[vadd_vx $V1, $V1, $T1]}
+    add $STATE1, $STATE1, $T1
+    lw $T0, 0($KEY)
+    # "2-by" little endian
+    li $T2, 0x79622d32
+    @{[vadd_vx $V2, $V2, $T2]}
+    add $STATE2, $STATE2, $T2
+    lw $T1, 4($KEY)
+    # "te k" little endian
+    li $T3, 0x6b206574
+    @{[vadd_vx $V3, $V3, $T3]}
+    add $STATE3, $STATE3, $T3
+    lw $T2, 8($KEY)
+    @{[vadd_vx $V4, $V4, $T0]}
+    add $STATE4, $STATE4, $T0
+    lw $T3, 12($KEY)
+    @{[vadd_vx $V5, $V5, $T1]}
+    add $STATE5, $STATE5, $T1
+    @{[vadd_vx $V6, $V6, $T2]}
+    add $STATE6, $STATE6, $T2
+    @{[vadd_vx $V7, $V7, $T3]}
+    add $STATE7, $STATE7, $T3
+
+    # xor with the top-half input
+    @{[vxor_vv $V16, $V16, $V0]}
+    sw $STATE0, 0(sp)
+    sw $STATE1, 4(sp)
+    @{[vxor_vv $V17, $V17, $V1]}
+    sw $STATE2, 8(sp)
+    sw $STATE3, 12(sp)
+    @{[vxor_vv $V18, $V18, $V2]}
+    sw $STATE4, 16(sp)
+    sw $STATE5, 20(sp)
+    @{[vxor_vv $V19, $V19, $V3]}
+    sw $STATE6, 24(sp)
+    sw $STATE7, 28(sp)
+    @{[vxor_vv $V20, $V20, $V4]}
+    lw $T0, 16($KEY)
+    @{[vxor_vv $V21, $V21, $V5]}
+    lw $T1, 20($KEY)
+    @{[vxor_vv $V22, $V22, $V6]}
+    lw $T2, 24($KEY)
+    @{[vxor_vv $V23, $V23, $V7]}
+
+    # save the top-half of output
+    li $T3, 64
+    @{[vssseg_nf_e32_v 8, $V16, $OUTPUT, $T3]}
+
+    # add chacha bottom-half initial block states
+    @{[vadd_vx $V8, $V8, $T0]}
+    add $STATE8, $STATE8, $T0
+    lw $T3, 28($KEY)
+    @{[vadd_vx $V9, $V9, $T1]}
+    add $STATE9, $STATE9, $T1
+    lw $T0, 4($COUNTER)
+    @{[vadd_vx $V10, $V10, $T2]}
+    add $STATE10, $STATE10, $T2
+    lw $T1, 8($COUNTER)
+    @{[vadd_vx $V11, $V11, $T3]}
+    add $STATE11, $STATE11, $T3
+    lw $T2, 12($COUNTER)
+    @{[vid_v $V0]}
+    add $STATE12, $STATE12, $CURRENT_COUNTER
+    @{[vadd_vx $V12, $V12, $CURRENT_COUNTER]}
+    add $STATE12, $STATE12, $VL
+    @{[vadd_vx $V13, $V13, $T0]}
+    add $STATE13, $STATE13, $T0
+    @{[vadd_vx $V14, $V14, $T1]}
+    add $STATE14, $STATE14, $T1
+    @{[vadd_vx $V15, $V15, $T2]}
+    add $STATE15, $STATE15, $T2
+    @{[vadd_vv $V12, $V12, $V0]}
+    # xor with the bottom-half input
+    @{[vxor_vv $V24, $V24, $V8]}
+    sw $STATE8, 32(sp)
+    @{[vxor_vv $V25, $V25, $V9]}
+    sw $STATE9, 36(sp)
+    @{[vxor_vv $V26, $V26, $V10]}
+    sw $STATE10, 40(sp)
+    @{[vxor_vv $V27, $V27, $V11]}
+    sw $STATE11, 44(sp)
+    @{[vxor_vv $V29, $V29, $V13]}
+    sw $STATE12, 48(sp)
+    @{[vxor_vv $V28, $V28, $V12]}
+    sw $STATE13, 52(sp)
+    @{[vxor_vv $V30, $V30, $V14]}
+    sw $STATE14, 56(sp)
+    @{[vxor_vv $V31, $V31, $V15]}
+    sw $STATE15, 60(sp)
+
+    # save the bottom-half of output
+    li $T0, 64
+    addi $T1, $OUTPUT, 32
+    @{[vssseg_nf_e32_v 8, $V24, $T1, $T0]}
+
+    # the computed vector parts: `64 * VL`
+    slli $T0, $VL, 6
+
+    add $INPUT, $INPUT, $T0
+    add $OUTPUT, $OUTPUT, $T0
+    sub $LEN, $LEN, $T0
+    add $CURRENT_COUNTER, $CURRENT_COUNTER, $VL
+
+    # process the scalar data block
+    addi $CURRENT_COUNTER, $CURRENT_COUNTER, 1
+    li $T0, 64
+    @{[minu $T1, $LEN, $T0]}
+    sub $LEN, $LEN, $T1
+    mv $T2, sp
+.Lscalar_data_loop:
+    @{[vsetvli $VL, $T1, "e8", "m8", "ta", "ma"]}
+    @{[vle8_v $V8, $INPUT]}
+    @{[vle8_v $V16, $T2]}
+    @{[vxor_vv $V8, $V8, $V16]}
+    @{[vse8_v $V8, $OUTPUT]}
+    add $INPUT, $INPUT, $VL
+    add $OUTPUT, $OUTPUT, $VL
+    add $T2, $T2, $VL
+    sub $T1, $T1, $VL
+    bnez $T1, .Lscalar_data_loop
+
+    bnez $LEN, .Lblock_loop
+
+    addi sp, sp, 64
+    ld s0, 0(sp)
+    ld s1, 8(sp)
+    ld s2, 16(sp)
+    ld s3, 24(sp)
+    ld s4, 32(sp)
+    ld s5, 40(sp)
+    ld s6, 48(sp)
+    ld s7, 56(sp)
+    ld s8, 64(sp)
+    ld s9, 72(sp)
+    ld s10, 80(sp)
+    ld s11, 88(sp)
+    addi sp, sp, 96
+
+    ret
+.size ChaCha20_ctr32_zbb_zvkb,.-ChaCha20_ctr32_zbb_zvkb
+___
+
+print $code;
+
+close STDOUT or die "error closing STDOUT: $!";

+ 6 - 0
libs/openssl/crypto/chacha/build.info

@@ -22,14 +22,19 @@ IF[{- !$disabled{asm} -}]
 
 
   $CHACHAASM_c64xplus=chacha-c64xplus.s
   $CHACHAASM_c64xplus=chacha-c64xplus.s
 
 
+  $CHACHAASM_riscv64=chacha_riscv.c chacha_enc.c chacha-riscv64-zbb-zvkb.s
+  $CHACHADEF_riscv64=INCLUDE_C_CHACHA20
+
   # Now that we have defined all the arch specific variables, use the
   # Now that we have defined all the arch specific variables, use the
   # appropriate one
   # appropriate one
   IF[$CHACHAASM_{- $target{asm_arch} -}]
   IF[$CHACHAASM_{- $target{asm_arch} -}]
     $CHACHAASM=$CHACHAASM_{- $target{asm_arch} -}
     $CHACHAASM=$CHACHAASM_{- $target{asm_arch} -}
+    $CHACHADEF=$CHACHADEF_{- $target{asm_arch} -}
   ENDIF
   ENDIF
 ENDIF
 ENDIF
 
 
 SOURCE[../../libcrypto]=$CHACHAASM
 SOURCE[../../libcrypto]=$CHACHAASM
+DEFINE[../../libcrypto]=$CHACHADEF
 
 
 GENERATE[chacha-x86.S]=asm/chacha-x86.pl
 GENERATE[chacha-x86.S]=asm/chacha-x86.pl
 GENERATE[chacha-x86_64.s]=asm/chacha-x86_64.pl
 GENERATE[chacha-x86_64.s]=asm/chacha-x86_64.pl
@@ -48,3 +53,4 @@ GENERATE[chacha-s390x.S]=asm/chacha-s390x.pl
 GENERATE[chacha-ia64.S]=asm/chacha-ia64.pl
 GENERATE[chacha-ia64.S]=asm/chacha-ia64.pl
 GENERATE[chacha-ia64.s]=chacha-ia64.S
 GENERATE[chacha-ia64.s]=chacha-ia64.S
 GENERATE[chacha-loongarch64.S]=asm/chacha-loongarch64.pl
 GENERATE[chacha-loongarch64.S]=asm/chacha-loongarch64.pl
+GENERATE[chacha-riscv64-zbb-zvkb.s]=asm/chacha-riscv64-zbb-zvkb.pl

+ 7 - 3
libs/openssl/crypto/chacha/chacha_enc.c

@@ -90,9 +90,13 @@ static void chacha20_core(chacha_buf *output, const u32 input[16])
     }
     }
 }
 }
 
 
-void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
-                    size_t len, const unsigned int key[8],
-                    const unsigned int counter[4])
+#ifdef INCLUDE_C_CHACHA20
+void ChaCha20_ctr32_c(unsigned char *out, const unsigned char *inp, size_t len,
+                      const unsigned int key[8], const unsigned int counter[4])
+#else
+void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len,
+                    const unsigned int key[8], const unsigned int counter[4])
+#endif
 {
 {
     u32 input[16];
     u32 input[16];
     chacha_buf buf;
     chacha_buf buf;

+ 56 - 0
libs/openssl/crypto/chacha/chacha_riscv.c

@@ -0,0 +1,56 @@
+/*
+ * This file is dual-licensed, meaning that you can use it under your
+ * choice of either of the following two licenses:
+ *
+ * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ *
+ * or
+ *
+ * Copyright (c) 2023, Jerry Shih <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <openssl/opensslconf.h>
+#include "crypto/chacha.h"
+#include "crypto/riscv_arch.h"
+
+void ChaCha20_ctr32_zbb_zvkb(unsigned char *out, const unsigned char *inp,
+                             size_t len, const unsigned int key[8],
+                             const unsigned int counter[4]);
+
+void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len,
+                    const unsigned int key[8], const unsigned int counter[4])
+{
+    if (len > CHACHA_BLK_SIZE && RISCV_HAS_ZVKB() && RISCV_HAS_ZBB() &&
+        riscv_vlen() >= 128) {
+        ChaCha20_ctr32_zbb_zvkb(out, inp, len, key, counter);
+    } else {
+        ChaCha20_ctr32_c(out, inp, len, key, counter);
+    }
+}

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2010-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2010-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -95,7 +95,7 @@ int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
 
 
     if (in->nlast_block == -1)
     if (in->nlast_block == -1)
         return 0;
         return 0;
-    if ((bl = EVP_CIPHER_CTX_get_block_size(in->cctx)) < 0)
+    if ((bl = EVP_CIPHER_CTX_get_block_size(in->cctx)) == 0)
         return 0;
         return 0;
     if (!EVP_CIPHER_CTX_copy(out->cctx, in->cctx))
     if (!EVP_CIPHER_CTX_copy(out->cctx, in->cctx))
         return 0;
         return 0;
@@ -111,6 +111,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
               const EVP_CIPHER *cipher, ENGINE *impl)
               const EVP_CIPHER *cipher, ENGINE *impl)
 {
 {
     static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 };
     static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 };
+    int block_len;
 
 
     /* All zeros means restart */
     /* All zeros means restart */
     if (!key && !cipher && !impl && keylen == 0) {
     if (!key && !cipher && !impl && keylen == 0) {
@@ -119,7 +120,10 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
             return 0;
             return 0;
         if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
         if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
             return 0;
             return 0;
-        memset(ctx->tbl, 0, EVP_CIPHER_CTX_get_block_size(ctx->cctx));
+        block_len = EVP_CIPHER_CTX_get_block_size(ctx->cctx);
+        if (block_len == 0)
+            return 0;
+        memset(ctx->tbl, 0, block_len);
         ctx->nlast_block = 0;
         ctx->nlast_block = 0;
         return 1;
         return 1;
     }
     }
@@ -170,7 +174,7 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
         return 0;
         return 0;
     if (dlen == 0)
     if (dlen == 0)
         return 1;
         return 1;
-    if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) < 0)
+    if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) == 0)
         return 0;
         return 0;
     /* Copy into partial block if we need to */
     /* Copy into partial block if we need to */
     if (ctx->nlast_block > 0) {
     if (ctx->nlast_block > 0) {
@@ -234,7 +238,7 @@ int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
 
 
     if (ctx->nlast_block == -1)
     if (ctx->nlast_block == -1)
         return 0;
         return 0;
-    if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) < 0)
+    if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) == 0)
         return 0;
         return 0;
     if (poutlen != NULL)
     if (poutlen != NULL)
         *poutlen = (size_t)bl;
         *poutlen = (size_t)bl;

+ 36 - 18
libs/openssl/crypto/cmp/cmp_asn.c

@@ -58,11 +58,7 @@ IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT)
 ASN1_SEQUENCE(OSSL_CMP_ERRORMSGCONTENT) = {
 ASN1_SEQUENCE(OSSL_CMP_ERRORMSGCONTENT) = {
     ASN1_SIMPLE(OSSL_CMP_ERRORMSGCONTENT, pKIStatusInfo, OSSL_CMP_PKISI),
     ASN1_SIMPLE(OSSL_CMP_ERRORMSGCONTENT, pKIStatusInfo, OSSL_CMP_PKISI),
     ASN1_OPT(OSSL_CMP_ERRORMSGCONTENT, errorCode, ASN1_INTEGER),
     ASN1_OPT(OSSL_CMP_ERRORMSGCONTENT, errorCode, ASN1_INTEGER),
-    /*
-     * OSSL_CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING
-     * so it is used directly
-     *
-     */
+    /* OSSL_CMP_PKIFREETEXT is a ASN1_UTF8STRING sequence, so used directly */
     ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ERRORMSGCONTENT, errorDetails,
     ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ERRORMSGCONTENT, errorDetails,
                          ASN1_UTF8STRING)
                          ASN1_UTF8STRING)
 } ASN1_SEQUENCE_END(OSSL_CMP_ERRORMSGCONTENT)
 } ASN1_SEQUENCE_END(OSSL_CMP_ERRORMSGCONTENT)
@@ -121,6 +117,9 @@ ASN1_ADB(OSSL_CMP_ITAV) = {
     ADB_ENTRY(NID_id_it_rootCaKeyUpdate,
     ADB_ENTRY(NID_id_it_rootCaKeyUpdate,
               ASN1_OPT(OSSL_CMP_ITAV, infoValue.rootCaKeyUpdate,
               ASN1_OPT(OSSL_CMP_ITAV, infoValue.rootCaKeyUpdate,
                        OSSL_CMP_ROOTCAKEYUPDATE)),
                        OSSL_CMP_ROOTCAKEYUPDATE)),
+    ADB_ENTRY(NID_id_it_certProfile,
+              ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.certProfile,
+                                   ASN1_UTF8STRING)),
 } ASN1_ADB_END(OSSL_CMP_ITAV, 0, infoType, 0,
 } ASN1_ADB_END(OSSL_CMP_ITAV, 0, infoType, 0,
                &infotypeandvalue_default_tt, NULL);
                &infotypeandvalue_default_tt, NULL);
 
 
@@ -190,13 +189,40 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p,
     return 1;
     return 1;
 
 
  err:
  err:
-    if (created != 0) {
+    if (created) {
         sk_OSSL_CMP_ITAV_free(*itav_sk_p);
         sk_OSSL_CMP_ITAV_free(*itav_sk_p);
         *itav_sk_p = NULL;
         *itav_sk_p = NULL;
     }
     }
     return 0;
     return 0;
 }
 }
 
 
+OSSL_CMP_ITAV
+*OSSL_CMP_ITAV_new0_certProfile(STACK_OF(ASN1_UTF8STRING) *certProfile)
+{
+    OSSL_CMP_ITAV *itav;
+
+    if ((itav = OSSL_CMP_ITAV_new()) == NULL)
+        return NULL;
+    itav->infoType = OBJ_nid2obj(NID_id_it_certProfile);
+    itav->infoValue.certProfile = certProfile;
+    return itav;
+}
+
+int OSSL_CMP_ITAV_get0_certProfile(const OSSL_CMP_ITAV *itav,
+                                   STACK_OF(ASN1_UTF8STRING) **out)
+{
+    if (itav == NULL || out == NULL) {
+        ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if (OBJ_obj2nid(itav->infoType) != NID_id_it_certProfile) {
+        ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
+        return 0;
+    }
+    *out = itav->infoValue.certProfile;
+    return 1;
+}
+
 OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts)
 OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts)
 {
 {
     OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new();
     OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new();
@@ -334,7 +360,7 @@ int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a)
 }
 }
 
 
 static int ossl_cmp_msg_cb(int operation, ASN1_VALUE **pval,
 static int ossl_cmp_msg_cb(int operation, ASN1_VALUE **pval,
-                           const ASN1_ITEM *it, void *exarg)
+                           ossl_unused const ASN1_ITEM *it, void *exarg)
 {
 {
     OSSL_CMP_MSG *msg = (OSSL_CMP_MSG *)*pval;
     OSSL_CMP_MSG *msg = (OSSL_CMP_MSG *)*pval;
 
 
@@ -424,14 +450,9 @@ ASN1_ITEM_TEMPLATE_END(OSSL_CMP_PKISTATUS)
 
 
 ASN1_SEQUENCE(OSSL_CMP_PKISI) = {
 ASN1_SEQUENCE(OSSL_CMP_PKISI) = {
     ASN1_SIMPLE(OSSL_CMP_PKISI, status, OSSL_CMP_PKISTATUS),
     ASN1_SIMPLE(OSSL_CMP_PKISI, status, OSSL_CMP_PKISTATUS),
-    /*
-     * CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING
-     * so it is used directly
-     */
+    /* OSSL_CMP_PKIFREETEXT is a ASN1_UTF8STRING sequence, so used directly */
     ASN1_SEQUENCE_OF_OPT(OSSL_CMP_PKISI, statusString, ASN1_UTF8STRING),
     ASN1_SEQUENCE_OF_OPT(OSSL_CMP_PKISI, statusString, ASN1_UTF8STRING),
-    /*
-     * OSSL_CMP_PKIFAILUREINFO is effectively ASN1_BIT_STRING so used directly
-     */
+    /* OSSL_CMP_PKIFAILUREINFO is effectively ASN1_BIT_STRING, used directly */
     ASN1_OPT(OSSL_CMP_PKISI, failInfo, ASN1_BIT_STRING)
     ASN1_OPT(OSSL_CMP_PKISI, failInfo, ASN1_BIT_STRING)
 } ASN1_SEQUENCE_END(OSSL_CMP_PKISI)
 } ASN1_SEQUENCE_END(OSSL_CMP_PKISI)
 IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
 IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
@@ -548,10 +569,7 @@ ASN1_SEQUENCE(OSSL_CMP_PKIHEADER) = {
     ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, transactionID, ASN1_OCTET_STRING, 4),
     ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, transactionID, ASN1_OCTET_STRING, 4),
     ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, senderNonce, ASN1_OCTET_STRING, 5),
     ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, senderNonce, ASN1_OCTET_STRING, 5),
     ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, recipNonce, ASN1_OCTET_STRING, 6),
     ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, recipNonce, ASN1_OCTET_STRING, 6),
-    /*
-     * OSSL_CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING
-     * so it is used directly
-     */
+    /* OSSL_CMP_PKIFREETEXT is a ASN1_UTF8STRING sequence, so used directly */
     ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, freeText, ASN1_UTF8STRING, 7),
     ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, freeText, ASN1_UTF8STRING, 7),
     ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, generalInfo,
     ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, generalInfo,
                              OSSL_CMP_ITAV, 8)
                              OSSL_CMP_ITAV, 8)

+ 162 - 34
libs/openssl/crypto/cmp/cmp_client.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Nokia 2007-2019
  * Copyright Nokia 2007-2019
  * Copyright Siemens AG 2015-2019
  * Copyright Siemens AG 2015-2019
  *
  *
@@ -113,6 +113,23 @@ static int save_statusInfo(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si)
     return 1;
     return 1;
 }
 }
 
 
+static int is_crep_with_waiting(const OSSL_CMP_MSG *resp, int rid)
+{
+    OSSL_CMP_CERTREPMESSAGE *crepmsg;
+    OSSL_CMP_CERTRESPONSE *crep;
+    int bt = OSSL_CMP_MSG_get_bodytype(resp);
+
+    if (!IS_CREP(bt))
+        return 0;
+
+    crepmsg = resp->body->value.ip; /* same for cp and kup */
+    crep = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, rid);
+
+    return (crep != NULL
+            && ossl_cmp_pkisi_get_status(crep->status)
+            == OSSL_CMP_PKISTATUS_waiting);
+}
+
 /*-
 /*-
  * Perform the generic aspects of sending a request and receiving a response.
  * Perform the generic aspects of sending a request and receiving a response.
  * Returns 1 on success and provides the received PKIMESSAGE in *rep.
  * Returns 1 on success and provides the received PKIMESSAGE in *rep.
@@ -160,7 +177,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
     /* should print error queue since transfer_cb may call ERR_clear_error() */
     /* should print error queue since transfer_cb may call ERR_clear_error() */
     OSSL_CMP_CTX_print_errors(ctx);
     OSSL_CMP_CTX_print_errors(ctx);
 
 
-    ossl_cmp_log1(INFO, ctx, "sending %s", req_type_str);
+    if (ctx->server != NULL)
+        ossl_cmp_log1(INFO, ctx, "sending %s", req_type_str);
 
 
     *rep = (*transfer_cb)(ctx, req);
     *rep = (*transfer_cb)(ctx, req);
     ctx->msg_timeout = bak_msg_timeout;
     ctx->msg_timeout = bak_msg_timeout;
@@ -180,7 +198,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
      * Still we use this preliminary value already for a progress report because
      * Still we use this preliminary value already for a progress report because
      * the following msg verification may also produce log entries and may fail.
      * the following msg verification may also produce log entries and may fail.
      */
      */
-    ossl_cmp_log1(INFO, ctx, "received %s", ossl_cmp_bodytype_to_string(bt));
+    ossl_cmp_log2(INFO, ctx, "received %s%s", ossl_cmp_bodytype_to_string(bt),
+                  ossl_cmp_is_error_with_waiting(*rep) ? " (waiting)" : "");
 
 
     /* copy received extraCerts to ctx->extraCertsIn so they can be retrieved */
     /* copy received extraCerts to ctx->extraCertsIn so they can be retrieved */
     if (bt != OSSL_CMP_PKIBODY_POLLREP && bt != OSSL_CMP_PKIBODY_PKICONF
     if (bt != OSSL_CMP_PKIBODY_POLLREP && bt != OSSL_CMP_PKIBODY_PKICONF
@@ -191,9 +210,17 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
                                    expected_type))
                                    expected_type))
         return 0;
         return 0;
 
 
+    /*
+     * rep can have the expected response type, which during polling is pollRep.
+     * When polling, also any other non-error response (the final response)
+     * is fine here. When not yet polling, delayed delivery may be initiated
+     * by the server returning an error message with 'waiting' status (or a
+     * response message of expected type ip/cp/kup with 'waiting' status).
+     */
     if (bt == expected_type
     if (bt == expected_type
-        /* as an answer to polling, there could be IP/CP/KUP: */
-            || (IS_CREP(bt) && expected_type == OSSL_CMP_PKIBODY_POLLREP))
+        || (expected_type == OSSL_CMP_PKIBODY_POLLREP
+            ? bt != OSSL_CMP_PKIBODY_ERROR
+            : ossl_cmp_is_error_with_waiting(*rep)))
         return 1;
         return 1;
 
 
     /* received message type is not one of the expected ones (e.g., error) */
     /* received message type is not one of the expected ones (e.g., error) */
@@ -235,7 +262,7 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
 
 
 /*-
 /*-
  * When a 'waiting' PKIStatus has been received, this function is used to
  * When a 'waiting' PKIStatus has been received, this function is used to
- * poll, which should yield a pollRep or finally a CertRepMessage in ip/cp/kup.
+ * poll, which should yield a pollRep or the final response.
  * On receiving a pollRep, which includes a checkAfter value, it return this
  * On receiving a pollRep, which includes a checkAfter value, it return this
  * value if sleep == 0, else it sleeps as long as indicated and retries.
  * value if sleep == 0, else it sleeps as long as indicated and retries.
  *
  *
@@ -246,7 +273,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
  * Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value.
  * Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value.
  * Returns 1 on success and provides the received PKIMESSAGE in *rep.
  * Returns 1 on success and provides the received PKIMESSAGE in *rep.
  *           In this case the caller is responsible for freeing *rep.
  *           In this case the caller is responsible for freeing *rep.
- * Returns 0 on error (which includes the case that timeout has been reached).
+ * Returns 0 on error (which includes the cases that timeout has been reached
+ *           or a response with 'waiting' status has been received).
  */
  */
 static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
 static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
                              OSSL_CMP_MSG **rep, int *checkAfter)
                              OSSL_CMP_MSG **rep, int *checkAfter)
@@ -312,7 +340,7 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
                           str, check_after);
                           str, check_after);
 
 
             if (ctx->total_timeout != 0) { /* timeout is not infinite */
             if (ctx->total_timeout != 0) { /* timeout is not infinite */
-                const int exp = 5; /* expected max time per msg round trip */
+                const int exp = OSSL_CMP_EXPECTED_RESP_TIME;
                 int64_t time_left = (int64_t)(ctx->end_time - exp - time(NULL));
                 int64_t time_left = (int64_t)(ctx->end_time - exp - time(NULL));
 
 
                 if (time_left <= 0) {
                 if (time_left <= 0) {
@@ -335,9 +363,19 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
                     *checkAfter = (int)check_after;
                     *checkAfter = (int)check_after;
                 return -1; /* exits the loop */
                 return -1; /* exits the loop */
             }
             }
+        } else if (is_crep_with_waiting(prep, rid)
+                   || ossl_cmp_is_error_with_waiting(prep)) {
+            /* received status must not be 'waiting' */
+            (void)ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection,
+                                          OSSL_CMP_CTX_FAILINFO_badRequest,
+                                          "polling already started",
+                                          0 /* errorCode */, NULL);
+            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKISTATUS);
+            goto err;
         } else {
         } else {
-            ossl_cmp_info(ctx, "received ip/cp/kup after polling");
-            /* any other body type has been rejected by send_receive_check() */
+            ossl_cmp_info(ctx, "received final response after polling");
+            if (!ossl_cmp_ctx_set1_first_senderNonce(ctx, NULL))
+                return 0;
             break;
             break;
         }
         }
     }
     }
@@ -349,11 +387,63 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
 
 
     return 1;
     return 1;
  err:
  err:
+    (void)ossl_cmp_ctx_set1_first_senderNonce(ctx, NULL);
     OSSL_CMP_MSG_free(preq);
     OSSL_CMP_MSG_free(preq);
     OSSL_CMP_MSG_free(prep);
     OSSL_CMP_MSG_free(prep);
     return 0;
     return 0;
 }
 }
 
 
+static int save_senderNonce_if_waiting(OSSL_CMP_CTX *ctx,
+                                       const OSSL_CMP_MSG *rep, int rid)
+{
+    /*
+     * Lightweight CMP Profile section 4.4 states: the senderNonce of the
+     * preceding request message because this value will be needed for checking
+     * the recipNonce of the final response to be received after polling.
+     */
+    if ((is_crep_with_waiting(rep, rid)
+         || ossl_cmp_is_error_with_waiting(rep))
+        && !ossl_cmp_ctx_set1_first_senderNonce(ctx, ctx->senderNonce))
+        return 0;
+
+    return 1;
+}
+
+/*
+ * Send request and get response possibly with polling initiated by error msg.
+ * Polling for ip/cp/kup/ with 'waiting' status is handled by cert_response().
+ */
+static int send_receive_also_delayed(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
+                                     OSSL_CMP_MSG **rep, int expected_type)
+{
+
+    if (!send_receive_check(ctx, req, rep, expected_type))
+        return 0;
+
+    if (ossl_cmp_is_error_with_waiting(*rep)) {
+        if (!save_senderNonce_if_waiting(ctx, *rep, OSSL_CMP_CERTREQID_NONE))
+            return 0;
+        /* not modifying ctx->status during certConf and error exchanges */
+        if (expected_type != OSSL_CMP_PKIBODY_PKICONF
+            && !save_statusInfo(ctx, (*rep)->body->value.error->pKIStatusInfo))
+            return 0;
+
+        OSSL_CMP_MSG_free(*rep);
+        *rep = NULL;
+
+        if (poll_for_response(ctx, 1 /* can sleep */, OSSL_CMP_CERTREQID_NONE,
+                              rep, NULL /* checkAfter */) <= 0) {
+            ERR_raise(ERR_LIB_CMP, CMP_R_POLLING_FAILED);
+            return 0;
+        }
+    }
+    if (OSSL_CMP_MSG_get_bodytype(*rep) != expected_type) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
+        return 0;
+    }
+
+    return 1;
+}
 /*
 /*
  * Send certConf for IR, CR or KUR sequences and check response,
  * Send certConf for IR, CR or KUR sequences and check response,
  * not modifying ctx->status during the certConf exchange
  * not modifying ctx->status during the certConf exchange
@@ -370,7 +460,8 @@ int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int certReqId,
     if (certConf == NULL)
     if (certConf == NULL)
         goto err;
         goto err;
 
 
-    res = send_receive_check(ctx, certConf, &PKIconf, OSSL_CMP_PKIBODY_PKICONF);
+    res = send_receive_also_delayed(ctx, certConf, &PKIconf,
+                                    OSSL_CMP_PKIBODY_PKICONF);
 
 
  err:
  err:
     OSSL_CMP_MSG_free(certConf);
     OSSL_CMP_MSG_free(certConf);
@@ -394,7 +485,8 @@ int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info,
     if ((error = ossl_cmp_error_new(ctx, si, errorCode, details, 0)) == NULL)
     if ((error = ossl_cmp_error_new(ctx, si, errorCode, details, 0)) == NULL)
         goto err;
         goto err;
 
 
-    res = send_receive_check(ctx, error, &PKIconf, OSSL_CMP_PKIBODY_PKICONF);
+    res = send_receive_also_delayed(ctx, error,
+                                    &PKIconf, OSSL_CMP_PKIBODY_PKICONF);
 
 
  err:
  err:
     OSSL_CMP_MSG_free(error);
     OSSL_CMP_MSG_free(error);
@@ -515,7 +607,7 @@ int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info,
         if (X509_verify_cert(csc) <= 0)
         if (X509_verify_cert(csc) <= 0)
             goto err;
             goto err;
 
 
-        if (!ossl_x509_add_certs_new(&chain,  X509_STORE_CTX_get0_chain(csc),
+        if (!ossl_x509_add_certs_new(&chain, X509_STORE_CTX_get0_chain(csc),
                                      X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
                                      X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
                                      | X509_ADD_FLAG_NO_SS)) {
                                      | X509_ADD_FLAG_NO_SS)) {
             sk_X509_free(chain);
             sk_X509_free(chain);
@@ -564,48 +656,78 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
     EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx);
     EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx);
     int fail_info = 0; /* no failure */
     int fail_info = 0; /* no failure */
     const char *txt = NULL;
     const char *txt = NULL;
-    OSSL_CMP_CERTREPMESSAGE *crepmsg;
-    OSSL_CMP_CERTRESPONSE *crep;
+    OSSL_CMP_CERTREPMESSAGE *crepmsg = NULL;
+    OSSL_CMP_CERTRESPONSE *crep = NULL;
     OSSL_CMP_certConf_cb_t cb;
     OSSL_CMP_certConf_cb_t cb;
     X509 *cert;
     X509 *cert;
     char *subj = NULL;
     char *subj = NULL;
     int ret = 1;
     int ret = 1;
+    int rcvd_type;
+    OSSL_CMP_PKISI *si;
 
 
     if (!ossl_assert(ctx != NULL))
     if (!ossl_assert(ctx != NULL))
         return 0;
         return 0;
 
 
  retry:
  retry:
-    crepmsg = (*resp)->body->value.ip; /* same for cp and kup */
-    if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1) {
-        ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED);
-        return 0;
-    }
-    crep = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, rid);
-    if (crep == NULL)
-        return 0;
-    if (!save_statusInfo(ctx, crep->status))
-        return 0;
-    if (rid == OSSL_CMP_CERTREQID_NONE) { /* used for OSSL_CMP_PKIBODY_P10CR */
-        rid = ossl_cmp_asn1_get_int(crep->certReqId);
-        if (rid < OSSL_CMP_CERTREQID_NONE) {
-            ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
+    rcvd_type = OSSL_CMP_MSG_get_bodytype(*resp);
+    if (IS_CREP(rcvd_type)) {
+        crepmsg = (*resp)->body->value.ip; /* same for cp and kup */
+        if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1) {
+            ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED);
             return 0;
             return 0;
         }
         }
+        crep = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, rid);
+        if (crep == NULL)
+            return 0;
+        si = crep->status;
+
+        if (rid == OSSL_CMP_CERTREQID_NONE) {
+            /* for OSSL_CMP_PKIBODY_P10CR learn CertReqId from response */
+            rid = ossl_cmp_asn1_get_int(crep->certReqId);
+            if (rid < OSSL_CMP_CERTREQID_NONE) {
+                ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
+                return 0;
+            }
+        }
+    } else if (rcvd_type == OSSL_CMP_PKIBODY_ERROR) {
+        si = (*resp)->body->value.error->pKIStatusInfo;
+    } else {
+        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
+        return 0;
     }
     }
 
 
-    if (ossl_cmp_pkisi_get_status(crep->status) == OSSL_CMP_PKISTATUS_waiting) {
+    if (!save_statusInfo(ctx, si))
+        return 0;
+
+    if (ossl_cmp_pkisi_get_status(si) == OSSL_CMP_PKISTATUS_waiting) {
+        /*
+         * Here we allow both and error message with waiting indication
+         * as well as a certificate response with waiting indication, where
+         * its flavor (ip, cp, or kup) may not strictly match ir/cr/p10cr/kur.
+         */
         OSSL_CMP_MSG_free(*resp);
         OSSL_CMP_MSG_free(*resp);
         *resp = NULL;
         *resp = NULL;
         if ((ret = poll_for_response(ctx, sleep, rid, resp, checkAfter)) != 0) {
         if ((ret = poll_for_response(ctx, sleep, rid, resp, checkAfter)) != 0) {
             if (ret == -1) /* at this point implies sleep == 0 */
             if (ret == -1) /* at this point implies sleep == 0 */
                 return ret; /* waiting */
                 return ret; /* waiting */
-            goto retry; /* got ip/cp/kup, which may still indicate 'waiting' */
+            goto retry; /* got some response other than pollRep */
         } else {
         } else {
             ERR_raise(ERR_LIB_CMP, CMP_R_POLLING_FAILED);
             ERR_raise(ERR_LIB_CMP, CMP_R_POLLING_FAILED);
             return 0;
             return 0;
         }
         }
     }
     }
 
 
+    /* at this point, we have received ip/cp/kup/error without waiting */
+    if (rcvd_type == OSSL_CMP_PKIBODY_ERROR) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_RECEIVED_ERROR);
+        return 0;
+    }
+    /* here we are strict on the flavor of ip/cp/kup: must match request */
+    if (rcvd_type != expected_type) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
+        return 0;
+    }
+
     cert = get1_cert_status(ctx, (*resp)->body->type, crep);
     cert = get1_cert_status(ctx, (*resp)->body->type, crep);
     if (cert == NULL) {
     if (cert == NULL) {
         ERR_add_error_data(1, "; cannot extract certificate from response");
         ERR_add_error_data(1, "; cannot extract certificate from response");
@@ -618,7 +740,7 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
      * if the CMP server returned certificates in the caPubs field, copy them
      * if the CMP server returned certificates in the caPubs field, copy them
      * to the context so that they can be retrieved if necessary
      * to the context so that they can be retrieved if necessary
      */
      */
-    if (crepmsg->caPubs != NULL
+    if (crepmsg != NULL && crepmsg->caPubs != NULL
             && !ossl_cmp_ctx_set1_caPubs(ctx, crepmsg->caPubs))
             && !ossl_cmp_ctx_set1_caPubs(ctx, crepmsg->caPubs))
         return 0;
         return 0;
 
 
@@ -709,6 +831,9 @@ int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type,
     if (ctx->status != OSSL_CMP_PKISTATUS_waiting) { /* not polling already */
     if (ctx->status != OSSL_CMP_PKISTATUS_waiting) { /* not polling already */
         if (!initial_certreq(ctx, req_type, crm, &rep, rep_type))
         if (!initial_certreq(ctx, req_type, crm, &rep, rep_type))
             goto err;
             goto err;
+
+        if (!save_senderNonce_if_waiting(ctx, rep, rid))
+            return 0;
     } else {
     } else {
         if (req_type < 0)
         if (req_type < 0)
             return ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection,
             return ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection,
@@ -750,6 +875,9 @@ X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type,
     if (!initial_certreq(ctx, req_type, crm, &rep, rep_type))
     if (!initial_certreq(ctx, req_type, crm, &rep, rep_type))
         goto err;
         goto err;
 
 
+    if (!save_senderNonce_if_waiting(ctx, rep, rid))
+        return 0;
+
     if (cert_response(ctx, 1 /* sleep */, rid, &rep, NULL, req_type, rep_type)
     if (cert_response(ctx, 1 /* sleep */, rid, &rep, NULL, req_type, rep_type)
         <= 0)
         <= 0)
         goto err;
         goto err;
@@ -787,7 +915,7 @@ int OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx)
         goto end;
         goto end;
 
 
     ctx->status = OSSL_CMP_PKISTATUS_trans;
     ctx->status = OSSL_CMP_PKISTATUS_trans;
-    if (!send_receive_check(ctx, rr, &rp, OSSL_CMP_PKIBODY_RP))
+    if (!send_receive_also_delayed(ctx, rr, &rp, OSSL_CMP_PKIBODY_RP))
         goto end;
         goto end;
 
 
     rrep = rp->body->value.rp;
     rrep = rp->body->value.rp;
@@ -908,7 +1036,7 @@ STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx)
         goto err;
         goto err;
 
 
     ctx->status = OSSL_CMP_PKISTATUS_trans;
     ctx->status = OSSL_CMP_PKISTATUS_trans;
-    if (!send_receive_check(ctx, genm, &genp, OSSL_CMP_PKIBODY_GENP))
+    if (!send_receive_also_delayed(ctx, genm, &genp, OSSL_CMP_PKIBODY_GENP))
         goto err;
         goto err;
     ctx->status = OSSL_CMP_PKISTATUS_accepted;
     ctx->status = OSSL_CMP_PKISTATUS_accepted;
 
 

+ 13 - 1
libs/openssl/crypto/cmp/cmp_ctx.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Nokia 2007-2019
  * Copyright Nokia 2007-2019
  * Copyright Siemens AG 2015-2019
  * Copyright Siemens AG 2015-2019
  *
  *
@@ -183,6 +183,7 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
         && ossl_cmp_ctx_set1_caPubs(ctx, NULL)
         && ossl_cmp_ctx_set1_caPubs(ctx, NULL)
         && ossl_cmp_ctx_set1_extraCertsIn(ctx, NULL)
         && ossl_cmp_ctx_set1_extraCertsIn(ctx, NULL)
         && ossl_cmp_ctx_set1_validatedSrvCert(ctx, NULL)
         && ossl_cmp_ctx_set1_validatedSrvCert(ctx, NULL)
+        && ossl_cmp_ctx_set1_first_senderNonce(ctx, NULL)
         && OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
         && OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
         && OSSL_CMP_CTX_set1_senderNonce(ctx, NULL)
         && OSSL_CMP_CTX_set1_senderNonce(ctx, NULL)
         && ossl_cmp_ctx_set1_recipNonce(ctx, NULL);
         && ossl_cmp_ctx_set1_recipNonce(ctx, NULL);
@@ -226,6 +227,7 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
     ASN1_OCTET_STRING_free(ctx->transactionID);
     ASN1_OCTET_STRING_free(ctx->transactionID);
     ASN1_OCTET_STRING_free(ctx->senderNonce);
     ASN1_OCTET_STRING_free(ctx->senderNonce);
     ASN1_OCTET_STRING_free(ctx->recipNonce);
     ASN1_OCTET_STRING_free(ctx->recipNonce);
+    ASN1_OCTET_STRING_free(ctx->first_senderNonce);
     OSSL_CMP_ITAVs_free(ctx->geninfo_ITAVs);
     OSSL_CMP_ITAVs_free(ctx->geninfo_ITAVs);
     OSSL_STACK_OF_X509_free(ctx->extraCertsOut);
     OSSL_STACK_OF_X509_free(ctx->extraCertsOut);
 
 
@@ -534,6 +536,8 @@ int OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx)
     return 1;
     return 1;
 }
 }
 
 
+DEFINE_OSSL_CMP_CTX_get0(geninfo_ITAVs, STACK_OF(OSSL_CMP_ITAV))
+
 /* Add an itav for the body of outgoing general messages */
 /* Add an itav for the body of outgoing general messages */
 int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
 int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
 {
 {
@@ -812,6 +816,9 @@ DEFINE_set1_ASN1_OCTET_STRING(ossl_cmp_ctx, recipNonce)
 /* Stores the given nonce as the last senderNonce sent out */
 /* Stores the given nonce as the last senderNonce sent out */
 DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, senderNonce)
 DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, senderNonce)
 
 
+/* store the first req sender nonce for verifying delayed delivery */
+DEFINE_set1_ASN1_OCTET_STRING(ossl_cmp_ctx, first_senderNonce)
+
 /* Set the proxy server to use for HTTP(S) connections */
 /* Set the proxy server to use for HTTP(S) connections */
 DEFINE_OSSL_CMP_CTX_set1(proxy, char)
 DEFINE_OSSL_CMP_CTX_set1(proxy, char)
 
 
@@ -908,6 +915,9 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
     case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
     case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
         ctx->unprotectedErrors = val;
         ctx->unprotectedErrors = val;
         break;
         break;
+    case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS:
+        ctx->noCacheExtraCerts = val;
+        break;
     case OSSL_CMP_OPT_VALIDITY_DAYS:
     case OSSL_CMP_OPT_VALIDITY_DAYS:
         ctx->days = val;
         ctx->days = val;
         break;
         break;
@@ -993,6 +1003,8 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
         return ctx->unprotectedSend;
         return ctx->unprotectedSend;
     case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
     case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
         return ctx->unprotectedErrors;
         return ctx->unprotectedErrors;
+    case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS:
+        return ctx->noCacheExtraCerts;
     case OSSL_CMP_OPT_VALIDITY_DAYS:
     case OSSL_CMP_OPT_VALIDITY_DAYS:
         return ctx->days;
         return ctx->days;
     case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
     case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:

+ 8 - 1
libs/openssl/crypto/cmp/cmp_err.c

@@ -1,6 +1,6 @@
 /*
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -76,6 +76,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     "error validating protection"},
     "error validating protection"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE),
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE),
     "error validating signature"},
     "error validating signature"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_EXPECTED_POLLREQ), "expected pollreq"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_BUILDING_OWN_CHAIN),
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_BUILDING_OWN_CHAIN),
     "failed building own chain"},
     "failed building own chain"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
@@ -144,10 +145,14 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     "transactionid unmatched"},
     "transactionid unmatched"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"},
     {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_UNCLEAN_CTX), "unclean ctx"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CERTPROFILE),
+     "unexpected certprofile"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS),
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS),
     "unexpected pkistatus"},
     "unexpected pkistatus"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_POLLREQ), "unexpected pollreq"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PVNO), "unexpected pvno"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PVNO), "unexpected pvno"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_SENDER), "unexpected sender"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID),
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID),
     "unknown algorithm id"},
     "unknown algorithm id"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"},
@@ -156,6 +161,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     "unsupported algorithm"},
     "unsupported algorithm"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE),
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE),
     "unsupported key type"},
     "unsupported key type"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PKIBODY),
+    "unsupported pkibody"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC),
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC),
     "unsupported protection alg dhbasedmac"},
     "unsupported protection alg dhbasedmac"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_VALUE_TOO_LARGE), "value too large"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_VALUE_TOO_LARGE), "value too large"},

+ 10 - 0
libs/openssl/crypto/cmp/cmp_hdr.c

@@ -72,6 +72,16 @@ ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr)
     return hdr->recipNonce;
     return hdr->recipNonce;
 }
 }
 
 
+STACK_OF(OSSL_CMP_ITAV)
+    *OSSL_CMP_HDR_get0_geninfo_ITAVs(const OSSL_CMP_PKIHEADER *hdr)
+{
+    if (hdr == NULL) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+        return NULL;
+    }
+    return hdr->generalInfo;
+}
+
 /* a NULL-DN as an empty sequence of RDNs */
 /* a NULL-DN as an empty sequence of RDNs */
 int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name)
 int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name)
 {
 {

+ 10 - 1
libs/openssl/crypto/cmp/cmp_local.h

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Nokia 2007-2019
  * Copyright Nokia 2007-2019
  * Copyright Siemens AG 2015-2019
  * Copyright Siemens AG 2015-2019
  *
  *
@@ -64,6 +64,7 @@ struct ossl_cmp_ctx_st {
      * certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf
      * certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf
      */
      */
     int unprotectedErrors;
     int unprotectedErrors;
+    int noCacheExtraCerts;
     X509 *srvCert; /* certificate used to identify the server */
     X509 *srvCert; /* certificate used to identify the server */
     X509 *validatedSrvCert; /* caches any already validated server cert */
     X509 *validatedSrvCert; /* caches any already validated server cert */
     X509_NAME *expected_sender; /* expected sender in header of response */
     X509_NAME *expected_sender; /* expected sender in header of response */
@@ -95,6 +96,7 @@ struct ossl_cmp_ctx_st {
     ASN1_OCTET_STRING *transactionID; /* the current transaction ID */
     ASN1_OCTET_STRING *transactionID; /* the current transaction ID */
     ASN1_OCTET_STRING *senderNonce; /* last nonce sent */
     ASN1_OCTET_STRING *senderNonce; /* last nonce sent */
     ASN1_OCTET_STRING *recipNonce; /* last nonce received */
     ASN1_OCTET_STRING *recipNonce; /* last nonce received */
+    ASN1_OCTET_STRING *first_senderNonce; /* sender nonce when starting to poll */
     ASN1_UTF8STRING *freeText; /* optional string to include each msg */
     ASN1_UTF8STRING *freeText; /* optional string to include each msg */
     STACK_OF(OSSL_CMP_ITAV) *geninfo_ITAVs;
     STACK_OF(OSSL_CMP_ITAV) *geninfo_ITAVs;
     int implicitConfirm; /* set implicitConfirm in IR/KUR/CR messages */
     int implicitConfirm; /* set implicitConfirm in IR/KUR/CR messages */
@@ -254,6 +256,8 @@ struct ossl_cmp_itav_st {
         OSSL_CMP_MSGS *origPKIMessage;
         OSSL_CMP_MSGS *origPKIMessage;
         /* NID_id_it_suppLangTags - Supported Language Tags */
         /* NID_id_it_suppLangTags - Supported Language Tags */
         STACK_OF(ASN1_UTF8STRING) *suppLangTagsValue;
         STACK_OF(ASN1_UTF8STRING) *suppLangTagsValue;
+        /* NID_id_it_certProfile - Certificate Profile */
+        STACK_OF(ASN1_UTF8STRING) *certProfile;
         /* NID_id_it_caCerts - CA Certificates */
         /* NID_id_it_caCerts - CA Certificates */
         STACK_OF(X509) *caCerts;
         STACK_OF(X509) *caCerts;
         /* NID_id_it_rootCaCert - Root CA Certificate */
         /* NID_id_it_rootCaCert - Root CA Certificate */
@@ -821,6 +825,8 @@ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
 int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
 int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
                                  const ASN1_OCTET_STRING *nonce);
                                  const ASN1_OCTET_STRING *nonce);
 EVP_PKEY *ossl_cmp_ctx_get0_newPubkey(const OSSL_CMP_CTX *ctx);
 EVP_PKEY *ossl_cmp_ctx_get0_newPubkey(const OSSL_CMP_CTX *ctx);
+int ossl_cmp_ctx_set1_first_senderNonce(OSSL_CMP_CTX *ctx,
+                                        const ASN1_OCTET_STRING *nonce);
 
 
 /* from cmp_status.c */
 /* from cmp_status.c */
 int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
 int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
@@ -937,6 +943,7 @@ ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
 X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx,
 X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx,
                                       const OSSL_CMP_CERTRESPONSE *crep);
                                       const OSSL_CMP_CERTRESPONSE *crep);
 OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
 OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
+int ossl_cmp_is_error_with_waiting(const OSSL_CMP_MSG *msg);
 
 
 /* from cmp_protect.c */
 /* from cmp_protect.c */
 int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
 int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
@@ -956,6 +963,8 @@ int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx,
                          const OSSL_CMP_MSG *msg, int accept_RAVerified);
                          const OSSL_CMP_MSG *msg, int accept_RAVerified);
 
 
 /* from cmp_client.c */
 /* from cmp_client.c */
+/* expected max time per msg round trip, used for last try during polling: */
+# define OSSL_CMP_EXPECTED_RESP_TIME 2
 int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int certReqId,
 int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int certReqId,
                                int fail_info, const char *txt);
                                int fail_info, const char *txt);
 int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info,
 int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info,

+ 41 - 5
libs/openssl/crypto/cmp/cmp_msg.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Nokia 2007-2019
  * Copyright Nokia 2007-2019
  * Copyright Siemens AG 2015-2019
  * Copyright Siemens AG 2015-2019
  *
  *
@@ -100,6 +100,34 @@ int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG *msg)
     return msg->body->type;
     return msg->body->type;
 }
 }
 
 
+X509_PUBKEY *OSSL_CMP_MSG_get0_certreq_publickey(const OSSL_CMP_MSG *msg)
+{
+    const OSSL_CRMF_MSGS *reqs;
+    const OSSL_CRMF_MSG *crm;
+    const OSSL_CRMF_CERTTEMPLATE *tmpl;
+    X509_PUBKEY *pubkey;
+
+    switch (OSSL_CMP_MSG_get_bodytype(msg)) {
+    case OSSL_CMP_PKIBODY_IR:
+    case OSSL_CMP_PKIBODY_CR:
+    case OSSL_CMP_PKIBODY_KUR:
+        reqs = msg->body->value.ir; /* value.ir is same for cr and kur */
+        if ((crm = sk_OSSL_CRMF_MSG_value(reqs, 0)) == NULL) {
+            ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND);
+            return NULL;
+        }
+        if ((tmpl = OSSL_CRMF_MSG_get0_tmpl(crm)) == NULL
+            || (pubkey = OSSL_CRMF_CERTTEMPLATE_get0_publicKey(tmpl)) == NULL) {
+            ERR_raise(ERR_LIB_CMP, CRMF_R_POPO_MISSING_PUBLIC_KEY);
+            return NULL;
+        }
+        return pubkey;
+    default:
+        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
+        return NULL;
+    }
+}
+
 /* Add an extension to the referenced extension stack, which may be NULL */
 /* Add an extension to the referenced extension stack, which may be NULL */
 static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex)
 static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex)
 {
 {
@@ -542,8 +570,7 @@ OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx)
     } else if (ctx->p10CSR != NULL) {
     } else if (ctx->p10CSR != NULL) {
         pubkey = X509_REQ_get0_pubkey(ctx->p10CSR);
         pubkey = X509_REQ_get0_pubkey(ctx->p10CSR);
         subject = X509_REQ_get_subject_name(ctx->p10CSR);
         subject = X509_REQ_get_subject_name(ctx->p10CSR);
-    }
-    else {
+    } else {
         goto err;
         goto err;
     }
     }
 
 
@@ -984,8 +1011,7 @@ static int suitable_rid(const ASN1_INTEGER *certReqId, int rid)
         return 1;
         return 1;
 
 
     trid = ossl_cmp_asn1_get_int(certReqId);
     trid = ossl_cmp_asn1_get_int(certReqId);
-
-    if (trid == OSSL_CMP_CERTREQID_NONE) {
+    if (trid <= OSSL_CMP_CERTREQID_INVALID) {
         ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
         ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
         return 0;
         return 0;
     }
     }
@@ -1200,3 +1226,13 @@ int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg)
 {
 {
     return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg);
     return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg);
 }
 }
+
+int ossl_cmp_is_error_with_waiting(const OSSL_CMP_MSG *msg)
+{
+    if (!ossl_assert(msg != NULL))
+        return 0;
+
+    return (OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_ERROR
+            && ossl_cmp_pkisi_get_status(msg->body->value.error->pKIStatusInfo)
+            == OSSL_CMP_PKISTATUS_waiting);
+}

+ 165 - 63
libs/openssl/crypto/cmp/cmp_server.c

@@ -22,9 +22,10 @@
 /* the context for the generic CMP server */
 /* the context for the generic CMP server */
 struct ossl_cmp_srv_ctx_st
 struct ossl_cmp_srv_ctx_st
 {
 {
-    void *custom_ctx;  /* pointer to application-specific server context */
-    OSSL_CMP_CTX *ctx; /* Client CMP context, reusing transactionID etc. */
-    int certReqId; /* id of last ir/cr/kur, OSSL_CMP_CERTREQID_NONE for p10cr */
+    OSSL_CMP_CTX *ctx; /* CMP client context reused for transactionID etc. */
+    void *custom_ctx;  /* application-specific server context */
+    int certReqId;     /* of ir/cr/kur, OSSL_CMP_CERTREQID_NONE for p10cr */
+    int polling;       /* current transaction is in polling mode */
 
 
     OSSL_CMP_SRV_cert_request_cb_t process_cert_request;
     OSSL_CMP_SRV_cert_request_cb_t process_cert_request;
     OSSL_CMP_SRV_rr_cb_t process_rr;
     OSSL_CMP_SRV_rr_cb_t process_rr;
@@ -32,6 +33,8 @@ struct ossl_cmp_srv_ctx_st
     OSSL_CMP_SRV_error_cb_t process_error;
     OSSL_CMP_SRV_error_cb_t process_error;
     OSSL_CMP_SRV_certConf_cb_t process_certConf;
     OSSL_CMP_SRV_certConf_cb_t process_certConf;
     OSSL_CMP_SRV_pollReq_cb_t process_pollReq;
     OSSL_CMP_SRV_pollReq_cb_t process_pollReq;
+    OSSL_CMP_SRV_delayed_delivery_cb_t delayed_delivery;
+    OSSL_CMP_SRV_clean_transaction_cb_t clean_transaction;
 
 
     int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */
     int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */
     int acceptUnprotected;     /* Accept requests with no/invalid prot. */
     int acceptUnprotected;     /* Accept requests with no/invalid prot. */
@@ -59,6 +62,7 @@ OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq)
     if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL)
     if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL)
         goto err;
         goto err;
     ctx->certReqId = OSSL_CMP_CERTREQID_INVALID;
     ctx->certReqId = OSSL_CMP_CERTREQID_INVALID;
+    ctx->polling = 0;
 
 
     /* all other elements are initialized to 0 or NULL, respectively */
     /* all other elements are initialized to 0 or NULL, respectively */
     return ctx;
     return ctx;
@@ -89,6 +93,19 @@ int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
     return 1;
     return 1;
 }
 }
 
 
+int OSSL_CMP_SRV_CTX_init_trans(OSSL_CMP_SRV_CTX *srv_ctx,
+                                OSSL_CMP_SRV_delayed_delivery_cb_t delay,
+                                OSSL_CMP_SRV_clean_transaction_cb_t clean)
+{
+    if (srv_ctx == NULL) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+        return 0;
+    }
+    srv_ctx->delayed_delivery = delay;
+    srv_ctx->clean_transaction = clean;
+    return 1;
+}
+
 OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
 OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
 {
 {
     if (srv_ctx == NULL) {
     if (srv_ctx == NULL) {
@@ -149,6 +166,46 @@ int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
     return 1;
     return 1;
 }
 }
 
 
+/* return error msg with waiting status if polling is initiated, else NULL */
+static OSSL_CMP_MSG *delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx,
+                                      const OSSL_CMP_MSG *req)
+{
+    int ret;
+    unsigned long err;
+    int status = OSSL_CMP_PKISTATUS_waiting,
+        fail_info = 0, errorCode = 0;
+    const char *txt = NULL, *details = NULL;
+    OSSL_CMP_PKISI *si;
+    OSSL_CMP_MSG *msg;
+
+    if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL
+                     && srv_ctx->delayed_delivery != NULL))
+        return NULL;
+
+    ret = srv_ctx->delayed_delivery(srv_ctx, req);
+    if (ret == 0)
+        return NULL;
+    if (ret == 1) {
+        srv_ctx->polling = 1;
+    } else {
+        status = OSSL_CMP_PKISTATUS_rejection;
+        fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_systemFailure;
+        txt = "server application error";
+        err = ERR_peek_error();
+        errorCode = ERR_GET_REASON(err);
+        details = ERR_reason_error_string(err);
+    }
+
+    si = OSSL_CMP_STATUSINFO_new(status, fail_info, txt);
+    if (si == NULL)
+        return NULL;
+
+    msg = ossl_cmp_error_new(srv_ctx->ctx, si, errorCode, details,
+                             srv_ctx->sendUnprotectedErrors);
+    OSSL_CMP_PKISI_free(si);
+    return msg;
+}
+
 /*
 /*
  * Processes an ir/cr/p10cr/kur and returns a certification response.
  * Processes an ir/cr/p10cr/kur and returns a certification response.
  * Only handles the first certification request contained in req
  * Only handles the first certification request contained in req
@@ -195,15 +252,14 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
             ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
             ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
             return NULL;
             return NULL;
         }
         }
-
-        if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) {
+        if ((crm = sk_OSSL_CRMF_MSG_value(reqs, 0)) == NULL) {
             ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND);
             ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND);
             return NULL;
             return NULL;
         }
         }
         certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
         certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
-        if (certReqId != OSSL_CMP_CERTREQID) {
+        if (certReqId != OSSL_CMP_CERTREQID) { /* so far, only possible value */
             ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
             ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
-            return 0;
+            return NULL;
         }
         }
     }
     }
     srv_ctx->certReqId = certReqId;
     srv_ctx->certReqId = certReqId;
@@ -222,6 +278,8 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
                                            &certOut, &chainOut, &caPubs);
                                            &certOut, &chainOut, &caPubs);
         if (si == NULL)
         if (si == NULL)
             goto err;
             goto err;
+        if (ossl_cmp_pkisi_get_status(si) == OSSL_CMP_PKISTATUS_waiting)
+            srv_ctx->polling = 1;
         /* set OSSL_CMP_OPT_IMPLICIT_CONFIRM if and only if transaction ends */
         /* set OSSL_CMP_OPT_IMPLICIT_CONFIRM if and only if transaction ends */
         if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx,
         if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx,
                                      OSSL_CMP_OPT_IMPLICIT_CONFIRM,
                                      OSSL_CMP_OPT_IMPLICIT_CONFIRM,
@@ -265,9 +323,8 @@ static OSSL_CMP_MSG *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
         ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
         return NULL;
         return NULL;
     }
     }
-
-    if ((details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr,
-                                                OSSL_CMP_REVREQSID)) == NULL) {
+    details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr, 0);
+    if (details == NULL) {
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return NULL;
         return NULL;
     }
     }
@@ -356,7 +413,7 @@ static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
     } else {
     } else {
         if (num > 1)
         if (num > 1)
             ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored");
             ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored");
-        status = sk_OSSL_CMP_CERTSTATUS_value(ccc, OSSL_CMP_CERTREQID);
+        status = sk_OSSL_CMP_CERTSTATUS_value(ccc, 0);
     }
     }
 
 
     if (status != NULL) {
     if (status != NULL) {
@@ -387,38 +444,96 @@ static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
     return msg;
     return msg;
 }
 }
 
 
+/* pollReq is handled separately, to avoid recursive call */
+static OSSL_CMP_MSG *process_non_polling_request(OSSL_CMP_SRV_CTX *srv_ctx,
+                                                 const OSSL_CMP_MSG *req)
+{
+    OSSL_CMP_MSG *rsp = NULL;
+
+    if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL
+                     && req->body != NULL))
+        return NULL;
+
+    switch (OSSL_CMP_MSG_get_bodytype(req)) {
+    case OSSL_CMP_PKIBODY_IR:
+    case OSSL_CMP_PKIBODY_CR:
+    case OSSL_CMP_PKIBODY_P10CR:
+    case OSSL_CMP_PKIBODY_KUR:
+        if (srv_ctx->process_cert_request == NULL)
+            ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
+        else
+            rsp = process_cert_request(srv_ctx, req);
+        break;
+    case OSSL_CMP_PKIBODY_RR:
+        if (srv_ctx->process_rr == NULL)
+            ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
+        else
+            rsp = process_rr(srv_ctx, req);
+        break;
+    case OSSL_CMP_PKIBODY_GENM:
+        if (srv_ctx->process_genm == NULL)
+            ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
+        else
+            rsp = process_genm(srv_ctx, req);
+        break;
+    case OSSL_CMP_PKIBODY_ERROR:
+        if (srv_ctx->process_error == NULL)
+            ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
+        else
+            rsp = process_error(srv_ctx, req);
+        break;
+    case OSSL_CMP_PKIBODY_CERTCONF:
+        if (srv_ctx->process_certConf == NULL)
+            ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
+        else
+            rsp = process_certConf(srv_ctx, req);
+        break;
+
+    case OSSL_CMP_PKIBODY_POLLREQ:
+        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
+        break;
+    default:
+        ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
+        break;
+    }
+
+    return rsp;
+}
+
 static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
 static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
                                      const OSSL_CMP_MSG *req)
                                      const OSSL_CMP_MSG *req)
 {
 {
     OSSL_CMP_POLLREQCONTENT *prc;
     OSSL_CMP_POLLREQCONTENT *prc;
     OSSL_CMP_POLLREQ *pr;
     OSSL_CMP_POLLREQ *pr;
     int certReqId;
     int certReqId;
-    OSSL_CMP_MSG *certReq;
+    OSSL_CMP_MSG *orig_req;
     int64_t check_after = 0;
     int64_t check_after = 0;
     OSSL_CMP_MSG *msg = NULL;
     OSSL_CMP_MSG *msg = NULL;
 
 
     if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
     if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
         return NULL;
         return NULL;
 
 
+    if (!srv_ctx->polling) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
+        return NULL;
+    }
+
     prc = req->body->value.pollReq;
     prc = req->body->value.pollReq;
     if (sk_OSSL_CMP_POLLREQ_num(prc) != 1) {
     if (sk_OSSL_CMP_POLLREQ_num(prc) != 1) {
         ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
         ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
         return NULL;
         return NULL;
     }
     }
 
 
-    pr = sk_OSSL_CMP_POLLREQ_value(prc, OSSL_CMP_CERTREQID);
+    pr = sk_OSSL_CMP_POLLREQ_value(prc, 0);
     certReqId = ossl_cmp_asn1_get_int(pr->certReqId);
     certReqId = ossl_cmp_asn1_get_int(pr->certReqId);
-    if (certReqId != srv_ctx->certReqId) {
-        ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
-        return NULL;
-    }
     if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId,
     if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId,
-                                  &certReq, &check_after))
+                                  &orig_req, &check_after))
         return NULL;
         return NULL;
 
 
-    if (certReq != NULL) {
-        msg = process_cert_request(srv_ctx, certReq);
-        OSSL_CMP_MSG_free(certReq);
+    if (orig_req != NULL) {
+        srv_ctx->polling = 0;
+        msg = process_non_polling_request(srv_ctx, orig_req);
+        OSSL_CMP_MSG_free(orig_req);
     } else {
     } else {
         if ((msg = ossl_cmp_pollRep_new(srv_ctx->ctx, certReqId,
         if ((msg = ossl_cmp_pollRep_new(srv_ctx->ctx, certReqId,
                                         check_after)) == NULL)
                                         check_after)) == NULL)
@@ -488,6 +603,12 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
     if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName))
     if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName))
         goto err;
         goto err;
 
 
+    if (srv_ctx->polling && req_type != OSSL_CMP_PKIBODY_POLLREQ
+            && req_type != OSSL_CMP_PKIBODY_ERROR) {
+        ERR_raise(ERR_LIB_CMP, CMP_R_EXPECTED_POLLREQ);
+        goto err;
+    }
+
     switch (req_type) {
     switch (req_type) {
     case OSSL_CMP_PKIBODY_IR:
     case OSSL_CMP_PKIBODY_IR:
     case OSSL_CMP_PKIBODY_CR:
     case OSSL_CMP_PKIBODY_CR:
@@ -509,6 +630,13 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
         if (!OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
         if (!OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
                 || !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL))
                 || !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL))
             goto err;
             goto err;
+
+        if (srv_ctx->clean_transaction != NULL
+                && !srv_ctx->clean_transaction(srv_ctx, NULL)) {
+            ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
+            goto err;
+        }
+
         break;
         break;
     default:
     default:
         /* transactionID should be already initialized */
         /* transactionID should be already initialized */
@@ -528,50 +656,17 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
     if (!req_verified)
     if (!req_verified)
         goto err;
         goto err;
 
 
-    switch (req_type) {
-    case OSSL_CMP_PKIBODY_IR:
-    case OSSL_CMP_PKIBODY_CR:
-    case OSSL_CMP_PKIBODY_P10CR:
-    case OSSL_CMP_PKIBODY_KUR:
-        if (srv_ctx->process_cert_request == NULL)
-            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
-        else
-            rsp = process_cert_request(srv_ctx, req);
-        break;
-    case OSSL_CMP_PKIBODY_RR:
-        if (srv_ctx->process_rr == NULL)
-            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
-        else
-            rsp = process_rr(srv_ctx, req);
-        break;
-    case OSSL_CMP_PKIBODY_GENM:
-        if (srv_ctx->process_genm == NULL)
-            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
-        else
-            rsp = process_genm(srv_ctx, req);
-        break;
-    case OSSL_CMP_PKIBODY_ERROR:
-        if (srv_ctx->process_error == NULL)
-            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
-        else
-            rsp = process_error(srv_ctx, req);
-        break;
-    case OSSL_CMP_PKIBODY_CERTCONF:
-        if (srv_ctx->process_certConf == NULL)
-            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
-        else
-            rsp = process_certConf(srv_ctx, req);
-        break;
-    case OSSL_CMP_PKIBODY_POLLREQ:
+    if (req_type == OSSL_CMP_PKIBODY_POLLREQ) {
         if (srv_ctx->process_pollReq == NULL)
         if (srv_ctx->process_pollReq == NULL)
-            ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
+            ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
         else
         else
             rsp = process_pollReq(srv_ctx, req);
             rsp = process_pollReq(srv_ctx, req);
-        break;
-    default:
-        /* Other request message types are not supported */
-        ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
-        break;
+    } else {
+        if (srv_ctx->delayed_delivery != NULL
+            && (rsp = delayed_delivery(srv_ctx, req)) != NULL) {
+            goto err;
+        }
+        rsp = process_non_polling_request(srv_ctx, req);
     }
     }
 
 
  err:
  err:
@@ -627,12 +722,19 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
             break;
             break;
         /* fall through */
         /* fall through */
 
 
+    case OSSL_CMP_PKIBODY_ERROR:
+        if (rsp != NULL && ossl_cmp_is_error_with_waiting(rsp))
+            break;
+        /* fall through */
+
     case OSSL_CMP_PKIBODY_RP:
     case OSSL_CMP_PKIBODY_RP:
     case OSSL_CMP_PKIBODY_PKICONF:
     case OSSL_CMP_PKIBODY_PKICONF:
     case OSSL_CMP_PKIBODY_GENP:
     case OSSL_CMP_PKIBODY_GENP:
-    case OSSL_CMP_PKIBODY_ERROR:
         /* Other terminating response message types are not supported */
         /* Other terminating response message types are not supported */
+        srv_ctx->certReqId = OSSL_CMP_CERTREQID_INVALID;
         /* Prepare for next transaction, ignoring any errors here: */
         /* Prepare for next transaction, ignoring any errors here: */
+        if (srv_ctx->clean_transaction != NULL)
+            (void)srv_ctx->clean_transaction(srv_ctx, ctx->transactionID);
         (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL);
         (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL);
         (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL);
         (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL);
         ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */
         ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */

+ 89 - 60
libs/openssl/crypto/cmp/cmp_vfy.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Nokia 2007-2020
  * Copyright Nokia 2007-2020
  * Copyright Siemens AG 2015-2020
  * Copyright Siemens AG 2015-2020
  *
  *
@@ -175,8 +175,8 @@ static int check_name(const OSSL_CMP_CTX *ctx, int log_success,
     str = X509_NAME_oneline(actual_name, NULL, 0);
     str = X509_NAME_oneline(actual_name, NULL, 0);
     if (X509_NAME_cmp(actual_name, expect_name) == 0) {
     if (X509_NAME_cmp(actual_name, expect_name) == 0) {
         if (log_success && str != NULL)
         if (log_success && str != NULL)
-            ossl_cmp_log2(INFO, ctx, " subject matches %s: %s", expect_desc,
-                          str);
+            ossl_cmp_log3(INFO, ctx, " %s matches %s: %s",
+                          actual_desc, expect_desc, str);
         OPENSSL_free(str);
         OPENSSL_free(str);
         return 1;
         return 1;
     }
     }
@@ -424,14 +424,14 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
 {
 {
     int ret = 0;
     int ret = 0;
 
 
-    if (mode_3gpp
-            && ((!ctx->permitTAInExtraCertsForIR
-                     || OSSL_CMP_MSG_get_bodytype(msg) != OSSL_CMP_PKIBODY_IP)))
+    if (ctx->permitTAInExtraCertsForIR
+            && OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_IP)
+        ossl_cmp_info(ctx, mode_3gpp ?
+                      "normal mode failed; trying now 3GPP mode trusting extraCerts"
+                      : "trying first normal mode using trust store");
+    else if (mode_3gpp)
         return 0;
         return 0;
 
 
-    ossl_cmp_info(ctx,
-                  mode_3gpp ? "normal mode failed; trying now 3GPP mode trusting extraCerts"
-                            : "trying first normal mode using trust store");
     if (check_msg_with_certs(ctx, msg->extraCerts, "extraCerts",
     if (check_msg_with_certs(ctx, msg->extraCerts, "extraCerts",
                              NULL, NULL, msg, mode_3gpp))
                              NULL, NULL, msg, mode_3gpp))
         return 1;
         return 1;
@@ -705,64 +705,89 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
 {
 {
     OSSL_CMP_PKIHEADER *hdr;
     OSSL_CMP_PKIHEADER *hdr;
     const X509_NAME *expected_sender;
     const X509_NAME *expected_sender;
+    int num_untrusted, num_added, res;
 
 
     if (!ossl_assert(ctx != NULL && msg != NULL && msg->header != NULL))
     if (!ossl_assert(ctx != NULL && msg != NULL && msg->header != NULL))
         return 0;
         return 0;
     hdr = OSSL_CMP_MSG_get0_header(msg);
     hdr = OSSL_CMP_MSG_get0_header(msg);
 
 
-    /* validate sender name of received msg */
-    if (hdr->sender->type != GEN_DIRNAME) {
-        ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
-        return 0;
-    }
-    /*
-     * Compare actual sender name of response with expected sender name.
-     * Mitigates risk to accept misused PBM secret
-     * or misused certificate of an unauthorized entity of a trusted hierarchy.
-     */
+    /* If expected_sender is given, validate sender name of received msg */
     expected_sender = ctx->expected_sender;
     expected_sender = ctx->expected_sender;
     if (expected_sender == NULL && ctx->srvCert != NULL)
     if (expected_sender == NULL && ctx->srvCert != NULL)
         expected_sender = X509_get_subject_name(ctx->srvCert);
         expected_sender = X509_get_subject_name(ctx->srvCert);
-    if (!check_name(ctx, 0, "sender DN field", hdr->sender->d.directoryName,
-                    "expected sender", expected_sender))
-        return 0;
+    if (expected_sender != NULL) {
+        const X509_NAME *actual_sender;
+        char *str;
+
+        if (hdr->sender->type != GEN_DIRNAME) {
+            ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
+            return 0;
+        }
+        actual_sender = hdr->sender->d.directoryName;
+        /*
+         * Compare actual sender name of response with expected sender name.
+         * Mitigates risk of accepting misused PBM secret or
+         * misused certificate of an unauthorized entity of a trusted hierarchy.
+         */
+        if (!check_name(ctx, 0, "sender DN field", actual_sender,
+                        "expected sender", expected_sender)) {
+            str = X509_NAME_oneline(actual_sender, NULL, 0);
+            ERR_raise_data(ERR_LIB_CMP, CMP_R_UNEXPECTED_SENDER,
+                           str != NULL ? str : "<unknown>");
+            OPENSSL_free(str);
+            return 0;
+        }
+    }
     /* Note: if recipient was NULL-DN it could be learned here if needed */
     /* Note: if recipient was NULL-DN it could be learned here if needed */
 
 
-    if (sk_X509_num(msg->extraCerts) > 10)
-        ossl_cmp_warn(ctx,
-                      "received CMP message contains more than 10 extraCerts");
+    num_added = sk_X509_num(msg->extraCerts);
+    if (num_added > 10)
+        ossl_cmp_log1(WARN, ctx, "received CMP message contains %d extraCerts",
+                      num_added);
     /*
     /*
      * Store any provided extraCerts in ctx for use in OSSL_CMP_validate_msg()
      * Store any provided extraCerts in ctx for use in OSSL_CMP_validate_msg()
      * and for future use, such that they are available to ctx->certConf_cb and
      * and for future use, such that they are available to ctx->certConf_cb and
      * the peer does not need to send them again in the same transaction.
      * the peer does not need to send them again in the same transaction.
      * Note that it does not help validating the message before storing the
      * Note that it does not help validating the message before storing the
      * extraCerts because they do not belong to the protected msg part anyway.
      * extraCerts because they do not belong to the protected msg part anyway.
-     * For efficiency, the extraCerts are prepended so they get used first.
+     * The extraCerts are prepended. Allows simple removal if they shall not be
+     * cached. Also they get used first, which is likely good for efficiency.
      */
      */
-    if (!X509_add_certs(ctx->untrusted, msg->extraCerts,
-                        /* this allows self-signed certs */
-                        X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
-                        | X509_ADD_FLAG_PREPEND))
+    num_untrusted = ctx->untrusted == NULL ? 0 : sk_X509_num(ctx->untrusted);
+    res = ossl_x509_add_certs_new(&ctx->untrusted, msg->extraCerts,
+                                  /* this allows self-signed certs */
+                                  X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
+                                  | X509_ADD_FLAG_PREPEND);
+    num_added = (ctx->untrusted == NULL ? 0 : sk_X509_num(ctx->untrusted))
+        - num_untrusted;
+    if (!res) {
+        while (num_added-- > 0)
+            X509_free(sk_X509_shift(ctx->untrusted));
         return 0;
         return 0;
+    }
 
 
-    /* validate message protection */
-    if (hdr->protectionAlg != NULL) {
-        /* detect explicitly permitted exceptions for invalid protection */
-        if (!OSSL_CMP_validate_msg(ctx, msg)
-                && (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) {
-#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-            ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_PROTECTION);
-            return 0;
+    if (hdr->protectionAlg != NULL)
+        res = OSSL_CMP_validate_msg(ctx, msg)
+            /* explicitly permitted exceptions for invalid protection: */
+            || (cb != NULL && (*cb)(ctx, msg, 1, cb_arg) > 0);
+    else
+        /* explicitly permitted exceptions for missing protection: */
+        res = cb != NULL && (*cb)(ctx, msg, 0, cb_arg) > 0;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    res = 1; /* support more aggressive fuzzing by letting invalid msg pass */
 #endif
 #endif
-        }
-    } else {
-        /* detect explicitly permitted exceptions for missing protection */
-        if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) {
-#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+
+    /* remove extraCerts again if not caching */
+    if (ctx->noCacheExtraCerts)
+        while (num_added-- > 0)
+            X509_free(sk_X509_shift(ctx->untrusted));
+
+    if (!res) {
+        if (hdr->protectionAlg != NULL)
+            ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_PROTECTION);
+        else
             ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PROTECTION);
             ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PROTECTION);
-            return 0;
-#endif
-        }
+        return 0;
     }
     }
 
 
     /* check CMP version number in header */
     /* check CMP version number in header */
@@ -786,10 +811,26 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
                                       CMP_R_TRANSACTIONID_UNMATCHED))
                                       CMP_R_TRANSACTIONID_UNMATCHED))
         return 0;
         return 0;
 
 
+    /*
+     * enable clearing irrelevant errors
+     * in attempts to validate recipient nonce in case of delayed delivery.
+     */
+    (void)ERR_set_mark();
     /* compare received nonce with the one we sent */
     /* compare received nonce with the one we sent */
     if (!check_transactionID_or_nonce(ctx->senderNonce, hdr->recipNonce,
     if (!check_transactionID_or_nonce(ctx->senderNonce, hdr->recipNonce,
-                                      CMP_R_RECIPNONCE_UNMATCHED))
-        return 0;
+                                      CMP_R_RECIPNONCE_UNMATCHED)) {
+        /* check if we are polling and received final response */
+        if (ctx->first_senderNonce == NULL
+            || OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_POLLREP
+            /* compare received nonce with our sender nonce at poll start */
+            || !check_transactionID_or_nonce(ctx->first_senderNonce,
+                                             hdr->recipNonce,
+                                             CMP_R_RECIPNONCE_UNMATCHED)) {
+            (void)ERR_clear_last_mark();
+            return 0;
+        }
+    }
+    (void)ERR_pop_to_mark();
 
 
     /* if not yet present, learn transactionID */
     /* if not yet present, learn transactionID */
     if (ctx->transactionID == NULL
     if (ctx->transactionID == NULL
@@ -804,18 +845,6 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
     if (!ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce))
     if (!ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce))
         return 0;
         return 0;
 
 
-    /*
-     * Store any provided extraCerts in ctx for future use,
-     * such that they are available to ctx->certConf_cb and
-     * the peer does not need to send them again in the same transaction.
-     * For efficiency, the extraCerts are prepended so they get used first.
-     */
-    if (!X509_add_certs(ctx->untrusted, msg->extraCerts,
-                        /* this allows self-signed certs */
-                        X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
-                        | X509_ADD_FLAG_PREPEND))
-        return 0;
-
     if (ossl_cmp_hdr_get_protection_nid(hdr) == NID_id_PasswordBasedMAC) {
     if (ossl_cmp_hdr_get_protection_nid(hdr) == NID_id_PasswordBasedMAC) {
         /*
         /*
          * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
          * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy

+ 9 - 1
libs/openssl/crypto/cms/cms_pwri.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2009-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -204,6 +204,10 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen,
     size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
     size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
     unsigned char *tmp;
     unsigned char *tmp;
     int outl, rv = 0;
     int outl, rv = 0;
+
+    if (blocklen == 0)
+        return 0;
+
     if (inlen < 2 * blocklen) {
     if (inlen < 2 * blocklen) {
         /* too small */
         /* too small */
         return 0;
         return 0;
@@ -257,6 +261,10 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
     size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
     size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
     size_t olen;
     size_t olen;
     int dummy;
     int dummy;
+
+    if (blocklen == 0)
+        return 0;
+
     /*
     /*
      * First decide length of output buffer: need header and round up to
      * First decide length of output buffer: need header and round up to
      * multiple of block length.
      * multiple of block length.

+ 1 - 1
libs/openssl/crypto/conf/conf_lib.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy

+ 92 - 47
libs/openssl/crypto/conf/conf_mod.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -11,6 +11,7 @@
 #define OPENSSL_SUPPRESS_DEPRECATED
 #define OPENSSL_SUPPRESS_DEPRECATED
 
 
 #include "internal/cryptlib.h"
 #include "internal/cryptlib.h"
+#include "internal/rcu.h"
 #include <stdio.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <ctype.h>
 #include <openssl/crypto.h>
 #include <openssl/crypto.h>
@@ -63,7 +64,7 @@ struct conf_imodule_st {
 };
 };
 
 
 static CRYPTO_ONCE init_module_list_lock = CRYPTO_ONCE_STATIC_INIT;
 static CRYPTO_ONCE init_module_list_lock = CRYPTO_ONCE_STATIC_INIT;
-static CRYPTO_RWLOCK *module_list_lock = NULL;
+static CRYPTO_RCU_LOCK *module_list_lock = NULL;
 static STACK_OF(CONF_MODULE) *supported_modules = NULL; /* protected by lock */
 static STACK_OF(CONF_MODULE) *supported_modules = NULL; /* protected by lock */
 static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; /* protected by lock */
 static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; /* protected by lock */
 
 
@@ -86,7 +87,7 @@ static int conf_modules_finish_int(void);
 
 
 static void module_lists_free(void)
 static void module_lists_free(void)
 {
 {
-    CRYPTO_THREAD_lock_free(module_list_lock);
+    ossl_rcu_lock_free(module_list_lock);
     module_list_lock = NULL;
     module_list_lock = NULL;
 
 
     sk_CONF_MODULE_free(supported_modules);
     sk_CONF_MODULE_free(supported_modules);
@@ -98,7 +99,7 @@ static void module_lists_free(void)
 
 
 DEFINE_RUN_ONCE_STATIC(do_init_module_list_lock)
 DEFINE_RUN_ONCE_STATIC(do_init_module_list_lock)
 {
 {
-    module_list_lock = CRYPTO_THREAD_lock_new();
+    module_list_lock = ossl_rcu_lock_new(1);
     if (module_list_lock == NULL) {
     if (module_list_lock == NULL) {
         ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
         ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
         return 0;
         return 0;
@@ -327,17 +328,24 @@ static CONF_MODULE *module_add(DSO *dso, const char *name,
                                conf_init_func *ifunc, conf_finish_func *ffunc)
                                conf_init_func *ifunc, conf_finish_func *ffunc)
 {
 {
     CONF_MODULE *tmod = NULL;
     CONF_MODULE *tmod = NULL;
+    STACK_OF(CONF_MODULE) *old_modules;
+    STACK_OF(CONF_MODULE) *new_modules;
 
 
     if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
     if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
         return NULL;
         return NULL;
 
 
-    if (!CRYPTO_THREAD_write_lock(module_list_lock))
-        return NULL;
+    ossl_rcu_write_lock(module_list_lock);
+
+    old_modules = ossl_rcu_deref(&supported_modules);
+
+    if (old_modules == NULL)
+        new_modules = sk_CONF_MODULE_new_null();
+    else
+        new_modules = sk_CONF_MODULE_dup(old_modules);
 
 
-    if (supported_modules == NULL)
-        supported_modules = sk_CONF_MODULE_new_null();
-    if (supported_modules == NULL)
+    if (new_modules == NULL)
         goto err;
         goto err;
+
     if ((tmod = OPENSSL_zalloc(sizeof(*tmod))) == NULL)
     if ((tmod = OPENSSL_zalloc(sizeof(*tmod))) == NULL)
         goto err;
         goto err;
 
 
@@ -348,18 +356,24 @@ static CONF_MODULE *module_add(DSO *dso, const char *name,
     if (tmod->name == NULL)
     if (tmod->name == NULL)
         goto err;
         goto err;
 
 
-    if (!sk_CONF_MODULE_push(supported_modules, tmod))
+    if (!sk_CONF_MODULE_push(new_modules, tmod))
         goto err;
         goto err;
 
 
-    CRYPTO_THREAD_unlock(module_list_lock);
+    ossl_rcu_assign_ptr(&supported_modules, &new_modules);
+    ossl_rcu_write_unlock(module_list_lock);
+    ossl_synchronize_rcu(module_list_lock);
+
+    sk_CONF_MODULE_free(old_modules);
     return tmod;
     return tmod;
 
 
  err:
  err:
-    CRYPTO_THREAD_unlock(module_list_lock);
+    ossl_rcu_write_unlock(module_list_lock);
+    sk_CONF_MODULE_free(new_modules);
     if (tmod != NULL) {
     if (tmod != NULL) {
         OPENSSL_free(tmod->name);
         OPENSSL_free(tmod->name);
         OPENSSL_free(tmod);
         OPENSSL_free(tmod);
     }
     }
+    sk_CONF_MODULE_free(new_modules);
     return NULL;
     return NULL;
 }
 }
 
 
@@ -374,6 +388,8 @@ static CONF_MODULE *module_find(const char *name)
     CONF_MODULE *tmod;
     CONF_MODULE *tmod;
     int i, nchar;
     int i, nchar;
     char *p;
     char *p;
+    STACK_OF(CONF_MODULE) *mods;
+
     p = strrchr(name, '.');
     p = strrchr(name, '.');
 
 
     if (p)
     if (p)
@@ -384,18 +400,18 @@ static CONF_MODULE *module_find(const char *name)
     if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
     if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
         return NULL;
         return NULL;
 
 
-    if (!CRYPTO_THREAD_read_lock(module_list_lock))
-        return NULL;
+    ossl_rcu_read_lock(module_list_lock);
+    mods = ossl_rcu_deref(&supported_modules);
 
 
-    for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) {
-        tmod = sk_CONF_MODULE_value(supported_modules, i);
+    for (i = 0; i < sk_CONF_MODULE_num(mods); i++) {
+        tmod = sk_CONF_MODULE_value(mods, i);
         if (strncmp(tmod->name, name, nchar) == 0) {
         if (strncmp(tmod->name, name, nchar) == 0) {
-            CRYPTO_THREAD_unlock(module_list_lock);
+            ossl_rcu_read_unlock(module_list_lock);
             return tmod;
             return tmod;
         }
         }
     }
     }
 
 
-    CRYPTO_THREAD_unlock(module_list_lock);
+    ossl_rcu_read_unlock(module_list_lock);
     return NULL;
     return NULL;
 }
 }
 
 
@@ -406,6 +422,8 @@ static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
     int ret = 1;
     int ret = 1;
     int init_called = 0;
     int init_called = 0;
     CONF_IMODULE *imod = NULL;
     CONF_IMODULE *imod = NULL;
+    STACK_OF(CONF_IMODULE) *old_modules;
+    STACK_OF(CONF_IMODULE) *new_modules;
 
 
     /* Otherwise add initialized module to list */
     /* Otherwise add initialized module to list */
     imod = OPENSSL_malloc(sizeof(*imod));
     imod = OPENSSL_malloc(sizeof(*imod));
@@ -432,27 +450,34 @@ static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
     if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
     if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
         goto err;
         goto err;
 
 
-    if (!CRYPTO_THREAD_write_lock(module_list_lock))
-        goto err;
+    ossl_rcu_write_lock(module_list_lock);
 
 
-    if (initialized_modules == NULL) {
-        initialized_modules = sk_CONF_IMODULE_new_null();
-        if (initialized_modules == NULL) {
-            CRYPTO_THREAD_unlock(module_list_lock);
-            ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
-            goto err;
-        }
+    old_modules = ossl_rcu_deref(&initialized_modules);
+
+    if (old_modules == NULL)
+        new_modules = sk_CONF_IMODULE_new_null();
+    else
+        new_modules = sk_CONF_IMODULE_dup(old_modules);
+
+    if (new_modules == NULL) {
+        ossl_rcu_write_unlock(module_list_lock);
+        ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
+        goto err;
     }
     }
 
 
-    if (!sk_CONF_IMODULE_push(initialized_modules, imod)) {
-        CRYPTO_THREAD_unlock(module_list_lock);
+    if (!sk_CONF_IMODULE_push(new_modules, imod)) {
+        ossl_rcu_write_unlock(module_list_lock);
+        sk_CONF_IMODULE_free(new_modules);
         ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
         ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
         goto err;
         goto err;
     }
     }
 
 
     pmod->links++;
     pmod->links++;
 
 
-    CRYPTO_THREAD_unlock(module_list_lock);
+    ossl_rcu_assign_ptr(&initialized_modules, &new_modules);
+    ossl_rcu_write_unlock(module_list_lock);
+    ossl_synchronize_rcu(module_list_lock);
+    sk_CONF_IMODULE_free(old_modules);
     return ret;
     return ret;
 
 
  err:
  err:
@@ -482,30 +507,46 @@ void CONF_modules_unload(int all)
 {
 {
     int i;
     int i;
     CONF_MODULE *md;
     CONF_MODULE *md;
+    STACK_OF(CONF_MODULE) *old_modules;
+    STACK_OF(CONF_MODULE) *new_modules;
+    STACK_OF(CONF_MODULE) *to_delete;
 
 
     if (!conf_modules_finish_int()) /* also inits module list lock */
     if (!conf_modules_finish_int()) /* also inits module list lock */
         return;
         return;
 
 
-    if (!CRYPTO_THREAD_write_lock(module_list_lock))
+    ossl_rcu_write_lock(module_list_lock);
+
+    old_modules = ossl_rcu_deref(&supported_modules);
+    new_modules = sk_CONF_MODULE_dup(old_modules);
+    to_delete = sk_CONF_MODULE_new_null();
+
+    if (new_modules == NULL) {
+        ossl_rcu_write_unlock(module_list_lock);
         return;
         return;
+    }
 
 
     /* unload modules in reverse order */
     /* unload modules in reverse order */
-    for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) {
-        md = sk_CONF_MODULE_value(supported_modules, i);
+    for (i = sk_CONF_MODULE_num(new_modules) - 1; i >= 0; i--) {
+        md = sk_CONF_MODULE_value(new_modules, i);
         /* If static or in use and 'all' not set ignore it */
         /* If static or in use and 'all' not set ignore it */
         if (((md->links > 0) || !md->dso) && !all)
         if (((md->links > 0) || !md->dso) && !all)
             continue;
             continue;
         /* Since we're working in reverse this is OK */
         /* Since we're working in reverse this is OK */
-        (void)sk_CONF_MODULE_delete(supported_modules, i);
-        module_free(md);
+        (void)sk_CONF_MODULE_delete(new_modules, i);
+        sk_CONF_MODULE_push(to_delete, md);
     }
     }
 
 
-    if (sk_CONF_MODULE_num(supported_modules) == 0) {
-        sk_CONF_MODULE_free(supported_modules);
-        supported_modules = NULL;
+    if (sk_CONF_MODULE_num(new_modules) == 0) {
+        sk_CONF_MODULE_free(new_modules);
+        new_modules = NULL;
     }
     }
 
 
-    CRYPTO_THREAD_unlock(module_list_lock);
+    ossl_rcu_assign_ptr(&supported_modules, &new_modules);
+    ossl_rcu_write_unlock(module_list_lock);
+    ossl_synchronize_rcu(module_list_lock);
+    sk_CONF_MODULE_free(old_modules);
+    sk_CONF_MODULE_pop_free(to_delete, module_free);
+
 }
 }
 
 
 /* unload a single module */
 /* unload a single module */
@@ -521,23 +562,27 @@ static void module_free(CONF_MODULE *md)
 static int conf_modules_finish_int(void)
 static int conf_modules_finish_int(void)
 {
 {
     CONF_IMODULE *imod;
     CONF_IMODULE *imod;
+    STACK_OF(CONF_IMODULE) *old_modules;
+    STACK_OF(CONF_IMODULE) *new_modules = NULL;
 
 
     if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
     if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
         return 0;
         return 0;
 
 
     /* If module_list_lock is NULL here it means we were already unloaded */
     /* If module_list_lock is NULL here it means we were already unloaded */
-    if (module_list_lock == NULL
-        || !CRYPTO_THREAD_write_lock(module_list_lock))
+    if (module_list_lock == NULL)
         return 0;
         return 0;
 
 
-    while (sk_CONF_IMODULE_num(initialized_modules) > 0) {
-        imod = sk_CONF_IMODULE_pop(initialized_modules);
+    ossl_rcu_write_lock(module_list_lock);
+    old_modules = ossl_rcu_deref(&initialized_modules);
+    ossl_rcu_assign_ptr(&initialized_modules, &new_modules);
+    ossl_rcu_write_unlock(module_list_lock);
+    ossl_synchronize_rcu(module_list_lock);
+
+    while (sk_CONF_IMODULE_num(old_modules) > 0) {
+        imod = sk_CONF_IMODULE_pop(old_modules);
         module_finish(imod);
         module_finish(imod);
     }
     }
-    sk_CONF_IMODULE_free(initialized_modules);
-    initialized_modules = NULL;
-
-    CRYPTO_THREAD_unlock(module_list_lock);
+    sk_CONF_IMODULE_free(old_modules);
 
 
     return 1;
     return 1;
 }
 }

+ 1 - 1
libs/openssl/crypto/conf/conf_sap.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy

+ 2 - 2
libs/openssl/crypto/dh/dh_check.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -351,7 +351,7 @@ int ossl_dh_check_pairwise(const DH *dh)
     /* recalculate the public key = (g ^ priv) mod p */
     /* recalculate the public key = (g ^ priv) mod p */
     if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key))
     if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key))
         goto err;
         goto err;
-    /* check it matches the existing pubic_key */
+    /* check it matches the existing public_key */
     ret = BN_cmp(pub_key, dh->pub_key) == 0;
     ret = BN_cmp(pub_key, dh->pub_key) == 0;
 err:
 err:
     BN_free(pub_key);
     BN_free(pub_key);

+ 1 - 1
libs/openssl/crypto/dsa/dsa_check.c

@@ -124,7 +124,7 @@ int ossl_dsa_check_pairwise(const DSA *dsa)
     /* recalculate the public key = (g ^ priv) mod p */
     /* recalculate the public key = (g ^ priv) mod p */
     if (!ossl_dsa_generate_public_key(ctx, dsa, dsa->priv_key, pub_key))
     if (!ossl_dsa_generate_public_key(ctx, dsa, dsa->priv_key, pub_key))
         goto err;
         goto err;
-    /* check it matches the existing pubic_key */
+    /* check it matches the existing public_key */
     ret = BN_cmp(pub_key, dsa->pub_key) == 0;
     ret = BN_cmp(pub_key, dsa->pub_key) == 0;
 err:
 err:
     BN_free(pub_key);
     BN_free(pub_key);

+ 2 - 2
libs/openssl/crypto/dso/dso_dl.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -217,7 +217,7 @@ static char *dl_name_converter(DSO *dso, const char *filename)
 
 
     len = strlen(filename);
     len = strlen(filename);
     rsize = len + 1;
     rsize = len + 1;
-    transform = (strstr(filename, "/") == NULL);
+    transform = (strchr(filename, '/') == NULL);
     if (transform) {
     if (transform) {
         /* We will convert this to "%s.s?" or "lib%s.s?" */
         /* We will convert this to "%s.s?" or "lib%s.s?" */
         rsize += strlen(DSO_EXTENSION); /* The length of ".s?" */
         rsize += strlen(DSO_EXTENSION); /* The length of ".s?" */

+ 2 - 2
libs/openssl/crypto/dso/dso_dlfcn.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -251,7 +251,7 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
 
 
     len = strlen(filename);
     len = strlen(filename);
     rsize = len + 1;
     rsize = len + 1;
-    transform = (strstr(filename, "/") == NULL);
+    transform = (strchr(filename, '/') == NULL);
     if (transform) {
     if (transform) {
         /* We will convert this to "%s.so" or "lib%s.so" etc */
         /* We will convert this to "%s.so" or "lib%s.so" etc */
         rsize += strlen(DSO_EXTENSION);    /* The length of ".so" */
         rsize += strlen(DSO_EXTENSION);    /* The length of ".so" */

+ 1 - 1
libs/openssl/crypto/ec/curve448/ed448.h

@@ -21,7 +21,7 @@
 /* Number of bytes in an EdDSA private key. */
 /* Number of bytes in an EdDSA private key. */
 # define EDDSA_448_PRIVATE_BYTES EDDSA_448_PUBLIC_BYTES
 # define EDDSA_448_PRIVATE_BYTES EDDSA_448_PUBLIC_BYTES
 
 
-/* Number of bytes in an EdDSA private key. */
+/* Number of bytes in an EdDSA signature. */
 # define EDDSA_448_SIGNATURE_BYTES (EDDSA_448_PUBLIC_BYTES + \
 # define EDDSA_448_SIGNATURE_BYTES (EDDSA_448_PUBLIC_BYTES + \
                                     EDDSA_448_PRIVATE_BYTES)
                                     EDDSA_448_PRIVATE_BYTES)
 
 

+ 13 - 0
libs/openssl/crypto/err/err_mark.c

@@ -26,6 +26,19 @@ int ERR_set_mark(void)
     return 1;
     return 1;
 }
 }
 
 
+int ERR_pop(void)
+{
+    ERR_STATE *es;
+
+    es = ossl_err_get_state_int();
+    if (es == NULL || es->bottom == es->top)
+        return 0;
+
+    err_clear(es, es->top, 0);
+    es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1;
+    return 1;
+}
+
 int ERR_pop_to_mark(void)
 int ERR_pop_to_mark(void)
 {
 {
     ERR_STATE *es;
     ERR_STATE *es;

+ 15 - 0
libs/openssl/crypto/err/openssl.txt

@@ -32,6 +32,7 @@ ASN1_R_EXPLICIT_LENGTH_MISMATCH:119:explicit length mismatch
 ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED:120:explicit tag not constructed
 ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED:120:explicit tag not constructed
 ASN1_R_FIELD_MISSING:121:field missing
 ASN1_R_FIELD_MISSING:121:field missing
 ASN1_R_FIRST_NUM_TOO_LARGE:122:first num too large
 ASN1_R_FIRST_NUM_TOO_LARGE:122:first num too large
+ASN1_R_GENERALIZEDTIME_IS_TOO_SHORT:232:generalizedtime is too short
 ASN1_R_HEADER_TOO_LONG:123:header too long
 ASN1_R_HEADER_TOO_LONG:123:header too long
 ASN1_R_ILLEGAL_BITSTRING_FORMAT:175:illegal bitstring format
 ASN1_R_ILLEGAL_BITSTRING_FORMAT:175:illegal bitstring format
 ASN1_R_ILLEGAL_BOOLEAN:176:illegal boolean
 ASN1_R_ILLEGAL_BOOLEAN:176:illegal boolean
@@ -119,6 +120,7 @@ ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE:164:unsupported any defined by type
 ASN1_R_UNSUPPORTED_CIPHER:228:unsupported cipher
 ASN1_R_UNSUPPORTED_CIPHER:228:unsupported cipher
 ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE:167:unsupported public key type
 ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE:167:unsupported public key type
 ASN1_R_UNSUPPORTED_TYPE:196:unsupported type
 ASN1_R_UNSUPPORTED_TYPE:196:unsupported type
+ASN1_R_UTCTIME_IS_TOO_SHORT:233:utctime is too short
 ASN1_R_WRONG_INTEGER_TYPE:225:wrong integer type
 ASN1_R_WRONG_INTEGER_TYPE:225:wrong integer type
 ASN1_R_WRONG_PUBLIC_KEY_TYPE:200:wrong public key type
 ASN1_R_WRONG_PUBLIC_KEY_TYPE:200:wrong public key type
 ASN1_R_WRONG_TAG:168:wrong tag
 ASN1_R_WRONG_TAG:168:wrong tag
@@ -227,6 +229,7 @@ CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash
 CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf
 CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf
 CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
 CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
 CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature
 CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature
+CMP_R_EXPECTED_POLLREQ:104:expected pollreq
 CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain
 CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain
 CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
 CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
 CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
 CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
@@ -272,14 +275,18 @@ CMP_R_TOTAL_TIMEOUT:184:total timeout
 CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched
 CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched
 CMP_R_TRANSFER_ERROR:159:transfer error
 CMP_R_TRANSFER_ERROR:159:transfer error
 CMP_R_UNCLEAN_CTX:191:unclean ctx
 CMP_R_UNCLEAN_CTX:191:unclean ctx
+CMP_R_UNEXPECTED_CERTPROFILE:196:unexpected certprofile
 CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody
 CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody
 CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus
 CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus
+CMP_R_UNEXPECTED_POLLREQ:105:unexpected pollreq
 CMP_R_UNEXPECTED_PVNO:153:unexpected pvno
 CMP_R_UNEXPECTED_PVNO:153:unexpected pvno
+CMP_R_UNEXPECTED_SENDER:106:unexpected sender
 CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id
 CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id
 CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type
 CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type
 CMP_R_UNKNOWN_PKISTATUS:186:unknown pkistatus
 CMP_R_UNKNOWN_PKISTATUS:186:unknown pkistatus
 CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm
 CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm
 CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type
 CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type
+CMP_R_UNSUPPORTED_PKIBODY:101:unsupported pkibody
 CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC:154:\
 CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC:154:\
 	unsupported protection alg dhbasedmac
 	unsupported protection alg dhbasedmac
 CMP_R_VALUE_TOO_LARGE:175:value too large
 CMP_R_VALUE_TOO_LARGE:175:value too large
@@ -830,6 +837,7 @@ HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http
 HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled
 HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled
 HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long
 HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long
 HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error
 HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error
+HTTP_R_RESPONSE_TOO_MANY_HDRLINES:130:response too many hdrlines
 HTTP_R_RETRY_TIMEOUT:129:retry timeout
 HTTP_R_RETRY_TIMEOUT:129:retry timeout
 HTTP_R_SERVER_CANCELED_CONNECTION:127:server canceled connection
 HTTP_R_SERVER_CANCELED_CONNECTION:127:server canceled connection
 HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported
 HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported
@@ -1396,6 +1404,8 @@ SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message
 SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch
 SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch
 SSL_R_FAILED_TO_GET_PARAMETER:316:failed to get parameter
 SSL_R_FAILED_TO_GET_PARAMETER:316:failed to get parameter
 SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async
 SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async
+SSL_R_FEATURE_NEGOTIATION_NOT_COMPLETE:417:feature negotiation not complete
+SSL_R_FEATURE_NOT_RENEGOTIABLE:413:feature not renegotiable
 SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello
 SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello
 SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs
 SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs
 SSL_R_HTTPS_PROXY_REQUEST:155:https proxy request
 SSL_R_HTTPS_PROXY_REQUEST:155:https proxy request
@@ -1500,6 +1510,7 @@ SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE:199:peer did not return a certificate
 SSL_R_PEM_NAME_BAD_PREFIX:391:pem name bad prefix
 SSL_R_PEM_NAME_BAD_PREFIX:391:pem name bad prefix
 SSL_R_PEM_NAME_TOO_SHORT:392:pem name too short
 SSL_R_PEM_NAME_TOO_SHORT:392:pem name too short
 SSL_R_PIPELINE_FAILURE:406:pipeline failure
 SSL_R_PIPELINE_FAILURE:406:pipeline failure
+SSL_R_POLL_REQUEST_NOT_SUPPORTED:418:poll request not supported
 SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR:278:post handshake auth encoding err
 SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR:278:post handshake auth encoding err
 SSL_R_PRIVATE_KEY_MISMATCH:288:private key mismatch
 SSL_R_PRIVATE_KEY_MISMATCH:288:private key mismatch
 SSL_R_PROTOCOL_IS_SHUTDOWN:207:protocol is shutdown
 SSL_R_PROTOCOL_IS_SHUTDOWN:207:protocol is shutdown
@@ -1632,10 +1643,14 @@ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED:338:\
 	unsafe legacy renegotiation disabled
 	unsafe legacy renegotiation disabled
 SSL_R_UNSOLICITED_EXTENSION:217:unsolicited extension
 SSL_R_UNSOLICITED_EXTENSION:217:unsolicited extension
 SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM:257:unsupported compression algorithm
 SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM:257:unsupported compression algorithm
+SSL_R_UNSUPPORTED_CONFIG_VALUE:414:unsupported config value
+SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS:415:unsupported config value class
+SSL_R_UNSUPPORTED_CONFIG_VALUE_OP:416:unsupported config value op
 SSL_R_UNSUPPORTED_ELLIPTIC_CURVE:315:unsupported elliptic curve
 SSL_R_UNSUPPORTED_ELLIPTIC_CURVE:315:unsupported elliptic curve
 SSL_R_UNSUPPORTED_PROTOCOL:258:unsupported protocol
 SSL_R_UNSUPPORTED_PROTOCOL:258:unsupported protocol
 SSL_R_UNSUPPORTED_SSL_VERSION:259:unsupported ssl version
 SSL_R_UNSUPPORTED_SSL_VERSION:259:unsupported ssl version
 SSL_R_UNSUPPORTED_STATUS_TYPE:329:unsupported status type
 SSL_R_UNSUPPORTED_STATUS_TYPE:329:unsupported status type
+SSL_R_UNSUPPORTED_WRITE_FLAG:412:unsupported write flag
 SSL_R_USE_SRTP_NOT_NEGOTIATED:369:use srtp not negotiated
 SSL_R_USE_SRTP_NOT_NEGOTIATED:369:use srtp not negotiated
 SSL_R_VERSION_TOO_HIGH:166:version too high
 SSL_R_VERSION_TOO_HIGH:166:version too high
 SSL_R_VERSION_TOO_LOW:396:version too low
 SSL_R_VERSION_TOO_LOW:396:version too low

+ 5 - 1
libs/openssl/crypto/evp/bio_enc.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -132,6 +132,10 @@ static int enc_read(BIO *b, char *out, int outl)
     }
     }
 
 
     blocksize = EVP_CIPHER_CTX_get_block_size(ctx->cipher);
     blocksize = EVP_CIPHER_CTX_get_block_size(ctx->cipher);
+
+    if (blocksize == 0)
+        return 0;
+
     if (blocksize == 1)
     if (blocksize == 1)
         blocksize = 0;
         blocksize = 0;
 
 

+ 35 - 2
libs/openssl/crypto/evp/digest.c

@@ -502,6 +502,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
     return ret;
     return ret;
 }
 }
 
 
+/* This is a one shot operation */
 int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
 int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
 {
 {
     int ret = 0;
     int ret = 0;
@@ -526,10 +527,15 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
         return 0;
         return 0;
     }
     }
 
 
+    /*
+     * For backward compatibility we pass the XOFLEN via a param here so that
+     * older providers can use the supplied value. Ideally we should have just
+     * used the size passed into ctx->digest->dfinal().
+     */
     params[i++] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &size);
     params[i++] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &size);
     params[i++] = OSSL_PARAM_construct_end();
     params[i++] = OSSL_PARAM_construct_end();
 
 
-    if (EVP_MD_CTX_set_params(ctx, params) > 0)
+    if (EVP_MD_CTX_set_params(ctx, params) >= 0)
         ret = ctx->digest->dfinal(ctx->algctx, md, &size, size);
         ret = ctx->digest->dfinal(ctx->algctx, md, &size, size);
 
 
     ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
     ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
@@ -553,6 +559,27 @@ legacy:
     return ret;
     return ret;
 }
 }
 
 
+/* EVP_DigestSqueeze() can be called multiple times */
+int EVP_DigestSqueeze(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
+{
+    if (ctx->digest == NULL) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM);
+        return 0;
+    }
+
+    if (ctx->digest->prov == NULL) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION);
+        return 0;
+    }
+
+    if (ctx->digest->dsqueeze == NULL) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_METHOD_NOT_SUPPORTED);
+        return 0;
+    }
+
+    return ctx->digest->dsqueeze(ctx->algctx, md, &size, size);
+}
+
 EVP_MD_CTX *EVP_MD_CTX_dup(const EVP_MD_CTX *in)
 EVP_MD_CTX *EVP_MD_CTX_dup(const EVP_MD_CTX *in)
 {
 {
     EVP_MD_CTX *out = EVP_MD_CTX_new();
     EVP_MD_CTX *out = EVP_MD_CTX_new();
@@ -1032,6 +1059,12 @@ static void *evp_md_from_algorithm(int name_id,
                 fncnt++;
                 fncnt++;
             }
             }
             break;
             break;
+        case OSSL_FUNC_DIGEST_SQUEEZE:
+            if (md->dsqueeze == NULL) {
+                md->dsqueeze = OSSL_FUNC_digest_squeeze(fns);
+                fncnt++;
+            }
+            break;
         case OSSL_FUNC_DIGEST_DIGEST:
         case OSSL_FUNC_DIGEST_DIGEST:
             if (md->digest == NULL)
             if (md->digest == NULL)
                 md->digest = OSSL_FUNC_digest_digest(fns);
                 md->digest = OSSL_FUNC_digest_digest(fns);
@@ -1075,7 +1108,7 @@ static void *evp_md_from_algorithm(int name_id,
             break;
             break;
         }
         }
     }
     }
-    if ((fncnt != 0 && fncnt != 5)
+    if ((fncnt != 0 && fncnt != 5 && fncnt != 6)
         || (fncnt == 0 && md->digest == NULL)) {
         || (fncnt == 0 && md->digest == NULL)) {
         /*
         /*
          * In order to be a consistent set of functions we either need the
          * In order to be a consistent set of functions we either need the

+ 13 - 13
libs/openssl/crypto/evp/evp_enc.c

@@ -253,7 +253,7 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
             memcpy(q++, p, sizeof(*q));
             memcpy(q++, p, sizeof(*q));
 
 
         /*
         /*
-         * Note that OSSL_CIPHER_PARAM_AEAD_IVLEN is a synomym for
+         * Note that OSSL_CIPHER_PARAM_AEAD_IVLEN is a synonym for
          * OSSL_CIPHER_PARAM_IVLEN so both are covered here.
          * OSSL_CIPHER_PARAM_IVLEN so both are covered here.
          */
          */
         p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN);
         p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN);
@@ -662,7 +662,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     size_t soutl, inl_ = (size_t)inl;
     size_t soutl, inl_ = (size_t)inl;
     int blocksize;
     int blocksize;
 
 
-    if (likely(outl != NULL)) {
+    if (ossl_likely(outl != NULL)) {
         *outl = 0;
         *outl = 0;
     } else {
     } else {
         ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
         ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
@@ -670,22 +670,22 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     }
     }
 
 
     /* Prevent accidental use of decryption context when encrypting */
     /* Prevent accidental use of decryption context when encrypting */
-    if (unlikely(!ctx->encrypt)) {
+    if (ossl_unlikely(!ctx->encrypt)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION);
         return 0;
         return 0;
     }
     }
 
 
-    if (unlikely(ctx->cipher == NULL)) {
+    if (ossl_unlikely(ctx->cipher == NULL)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
         return 0;
         return 0;
     }
     }
 
 
-    if (unlikely(ctx->cipher->prov == NULL))
+    if (ossl_unlikely(ctx->cipher->prov == NULL))
         goto legacy;
         goto legacy;
 
 
     blocksize = ctx->cipher->block_size;
     blocksize = ctx->cipher->block_size;
 
 
-    if (unlikely(ctx->cipher->cupdate == NULL || blocksize < 1)) {
+    if (ossl_unlikely(ctx->cipher->cupdate == NULL || blocksize < 1)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
         ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
         return 0;
         return 0;
     }
     }
@@ -694,7 +694,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
                                inl_ + (size_t)(blocksize == 1 ? 0 : blocksize),
                                inl_ + (size_t)(blocksize == 1 ? 0 : blocksize),
                                in, inl_);
                                in, inl_);
 
 
-    if (likely(ret)) {
+    if (ossl_likely(ret)) {
         if (soutl > INT_MAX) {
         if (soutl > INT_MAX) {
             ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
             ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
             return 0;
             return 0;
@@ -811,7 +811,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     size_t soutl, inl_ = (size_t)inl;
     size_t soutl, inl_ = (size_t)inl;
     int blocksize;
     int blocksize;
 
 
-    if (likely(outl != NULL)) {
+    if (ossl_likely(outl != NULL)) {
         *outl = 0;
         *outl = 0;
     } else {
     } else {
         ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
         ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
@@ -819,21 +819,21 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     }
     }
 
 
     /* Prevent accidental use of encryption context when decrypting */
     /* Prevent accidental use of encryption context when decrypting */
-    if (unlikely(ctx->encrypt)) {
+    if (ossl_unlikely(ctx->encrypt)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION);
         return 0;
         return 0;
     }
     }
 
 
-    if (unlikely(ctx->cipher == NULL)) {
+    if (ossl_unlikely(ctx->cipher == NULL)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
         return 0;
         return 0;
     }
     }
-    if (unlikely(ctx->cipher->prov == NULL))
+    if (ossl_unlikely(ctx->cipher->prov == NULL))
         goto legacy;
         goto legacy;
 
 
     blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
     blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
 
 
-    if (unlikely(ctx->cipher->cupdate == NULL || blocksize < 1)) {
+    if (ossl_unlikely(ctx->cipher->cupdate == NULL || blocksize < 1)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
         ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
         return 0;
         return 0;
     }
     }
@@ -841,7 +841,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
                                inl_ + (size_t)(blocksize == 1 ? 0 : blocksize),
                                inl_ + (size_t)(blocksize == 1 ? 0 : blocksize),
                                in, inl_);
                                in, inl_);
 
 
-    if (likely(ret)) {
+    if (ossl_likely(ret)) {
         if (soutl > INT_MAX) {
         if (soutl > INT_MAX) {
             ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
             ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
             return 0;
             return 0;

+ 1 - 1
libs/openssl/crypto/evp/evp_fetch.c

@@ -323,7 +323,7 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
              * will create a method against all names, but the lookup will fail
              * will create a method against all names, but the lookup will fail
              * as ossl_namemap_name2num treats the name string as a single name
              * as ossl_namemap_name2num treats the name string as a single name
              * rather than introducing new features where in the EVP_<obj>_fetch
              * rather than introducing new features where in the EVP_<obj>_fetch
-             * parses the string and querys for each, return an error.
+             * parses the string and queries for each, return an error.
              */
              */
             if (name_id == 0)
             if (name_id == 0)
                 name_id = ossl_namemap_name2num(namemap, name);
                 name_id = ossl_namemap_name2num(namemap, name);

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -88,7 +88,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
     nkey = EVP_CIPHER_get_key_length(type);
     nkey = EVP_CIPHER_get_key_length(type);
     niv = EVP_CIPHER_get_iv_length(type);
     niv = EVP_CIPHER_get_iv_length(type);
     OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
     OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
-    OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
+    OPENSSL_assert(niv >= 0 && niv <= EVP_MAX_IV_LENGTH);
 
 
     if (data == NULL)
     if (data == NULL)
         return nkey;
         return nkey;

+ 27 - 9
libs/openssl/crypto/evp/evp_lib.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -81,8 +81,12 @@ int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
                                 evp_cipher_aead_asn1_params *asn1_params)
                                 evp_cipher_aead_asn1_params *asn1_params)
 {
 {
     int ret = -1;                /* Assume the worst */
     int ret = -1;                /* Assume the worst */
-    const EVP_CIPHER *cipher = c->cipher;
+    const EVP_CIPHER *cipher;
 
 
+    if (c == NULL || c->cipher == NULL)
+        goto err;
+
+    cipher = c->cipher;
     /*
     /*
      * For legacy implementations, we detect custom AlgorithmIdentifier
      * For legacy implementations, we detect custom AlgorithmIdentifier
      * parameter handling by checking if the function pointer
      * parameter handling by checking if the function pointer
@@ -172,8 +176,12 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
                                 evp_cipher_aead_asn1_params *asn1_params)
                                 evp_cipher_aead_asn1_params *asn1_params)
 {
 {
     int ret = -1;                /* Assume the worst */
     int ret = -1;                /* Assume the worst */
-    const EVP_CIPHER *cipher = c->cipher;
+    const EVP_CIPHER *cipher;
+
+    if (c == NULL || c->cipher == NULL)
+        goto err;
 
 
+    cipher = c->cipher;
     /*
     /*
      * For legacy implementations, we detect custom AlgorithmIdentifier
      * For legacy implementations, we detect custom AlgorithmIdentifier
      * parameter handling by checking if there the function pointer
      * parameter handling by checking if there the function pointer
@@ -230,6 +238,7 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
         ret = -2;
         ret = -2;
     }
     }
 
 
+err:
     if (ret == -2)
     if (ret == -2)
         ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER);
         ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER);
     else if (ret <= 0)
     else if (ret <= 0)
@@ -387,7 +396,7 @@ int evp_cipher_cache_constants(EVP_CIPHER *cipher)
 
 
 int EVP_CIPHER_get_block_size(const EVP_CIPHER *cipher)
 int EVP_CIPHER_get_block_size(const EVP_CIPHER *cipher)
 {
 {
-    return cipher->block_size;
+    return (cipher == NULL) ? 0 : cipher->block_size;
 }
 }
 
 
 int EVP_CIPHER_CTX_get_block_size(const EVP_CIPHER_CTX *ctx)
 int EVP_CIPHER_CTX_get_block_size(const EVP_CIPHER_CTX *ctx)
@@ -403,6 +412,9 @@ int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
 int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                const unsigned char *in, unsigned int inl)
                const unsigned char *in, unsigned int inl)
 {
 {
+    if (ctx == NULL || ctx->cipher == NULL)
+        return 0;
+
     if (ctx->cipher->prov != NULL) {
     if (ctx->cipher->prov != NULL) {
         /*
         /*
          * If the provided implementation has a ccipher function, we use it,
          * If the provided implementation has a ccipher function, we use it,
@@ -415,6 +427,9 @@ int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
         size_t outl = 0;
         size_t outl = 0;
         size_t blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
         size_t blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
 
 
+        if (blocksize == 0)
+            return 0;
+
         if (ctx->cipher->ccipher != NULL)
         if (ctx->cipher->ccipher != NULL)
             ret =  ctx->cipher->ccipher(ctx->algctx, out, &outl,
             ret =  ctx->cipher->ccipher(ctx->algctx, out, &outl,
                                         inl + (blocksize == 1 ? 0 : blocksize),
                                         inl + (blocksize == 1 ? 0 : blocksize),
@@ -454,7 +469,7 @@ EVP_CIPHER *EVP_CIPHER_CTX_get1_cipher(EVP_CIPHER_CTX *ctx)
 {
 {
     EVP_CIPHER *cipher;
     EVP_CIPHER *cipher;
 
 
-    if (ctx == NULL)
+    if (ctx == NULL || ctx->cipher == NULL)
         return NULL;
         return NULL;
     cipher = (EVP_CIPHER *)ctx->cipher;
     cipher = (EVP_CIPHER *)ctx->cipher;
     if (!EVP_CIPHER_up_ref(cipher))
     if (!EVP_CIPHER_up_ref(cipher))
@@ -469,7 +484,7 @@ int EVP_CIPHER_CTX_is_encrypting(const EVP_CIPHER_CTX *ctx)
 
 
 unsigned long EVP_CIPHER_get_flags(const EVP_CIPHER *cipher)
 unsigned long EVP_CIPHER_get_flags(const EVP_CIPHER *cipher)
 {
 {
-    return cipher->flags;
+    return cipher == NULL ? 0 : cipher->flags;
 }
 }
 
 
 void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
 void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
@@ -499,11 +514,14 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
 
 
 int EVP_CIPHER_get_iv_length(const EVP_CIPHER *cipher)
 int EVP_CIPHER_get_iv_length(const EVP_CIPHER *cipher)
 {
 {
-    return cipher->iv_len;
+    return (cipher == NULL) ? 0 : cipher->iv_len;
 }
 }
 
 
 int EVP_CIPHER_CTX_get_iv_length(const EVP_CIPHER_CTX *ctx)
 int EVP_CIPHER_CTX_get_iv_length(const EVP_CIPHER_CTX *ctx)
 {
 {
+    if (ctx->cipher == NULL)
+        return 0;
+
     if (ctx->iv_len < 0) {
     if (ctx->iv_len < 0) {
         int rv, len = EVP_CIPHER_get_iv_length(ctx->cipher);
         int rv, len = EVP_CIPHER_get_iv_length(ctx->cipher);
         size_t v = len;
         size_t v = len;
@@ -678,12 +696,12 @@ int EVP_CIPHER_CTX_get_key_length(const EVP_CIPHER_CTX *ctx)
 
 
 int EVP_CIPHER_get_nid(const EVP_CIPHER *cipher)
 int EVP_CIPHER_get_nid(const EVP_CIPHER *cipher)
 {
 {
-    return cipher->nid;
+    return (cipher == NULL) ? NID_undef : cipher->nid;
 }
 }
 
 
 int EVP_CIPHER_CTX_get_nid(const EVP_CIPHER_CTX *ctx)
 int EVP_CIPHER_CTX_get_nid(const EVP_CIPHER_CTX *ctx)
 {
 {
-    return ctx->cipher->nid;
+    return EVP_CIPHER_get_nid(ctx->cipher);
 }
 }
 
 
 int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name)
 int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name)

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

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -95,6 +95,8 @@ struct evp_keymgmt_st {
     int id;                      /* libcrypto internal */
     int id;                      /* libcrypto internal */
 
 
     int name_id;
     int name_id;
+    /* NID for the legacy alg if there is one */
+    int legacy_alg;
     char *type_name;
     char *type_name;
     const char *description;
     const char *description;
     OSSL_PROVIDER *prov;
     OSSL_PROVIDER *prov;

+ 30 - 1
libs/openssl/crypto/evp/keymgmt_meth.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -30,6 +30,26 @@ static void *keymgmt_new(void)
     return keymgmt;
     return keymgmt;
 }
 }
 
 
+#ifndef FIPS_MODULE
+static void help_get_legacy_alg_type_from_keymgmt(const char *keytype,
+                                                  void *arg)
+{
+    int *type = arg;
+
+    if (*type == NID_undef)
+        *type = evp_pkey_name2type(keytype);
+}
+
+static int get_legacy_alg_type_from_keymgmt(const EVP_KEYMGMT *keymgmt)
+{
+    int type = NID_undef;
+
+    EVP_KEYMGMT_names_do_all(keymgmt, help_get_legacy_alg_type_from_keymgmt,
+                             &type);
+    return type;
+}
+#endif
+
 static void *keymgmt_from_algorithm(int name_id,
 static void *keymgmt_from_algorithm(int name_id,
                                     const OSSL_ALGORITHM *algodef,
                                     const OSSL_ALGORITHM *algodef,
                                     OSSL_PROVIDER *prov)
                                     OSSL_PROVIDER *prov)
@@ -218,6 +238,10 @@ static void *keymgmt_from_algorithm(int name_id,
     if (prov != NULL)
     if (prov != NULL)
         ossl_provider_up_ref(prov);
         ossl_provider_up_ref(prov);
 
 
+#ifndef FIPS_MODULE
+    keymgmt->legacy_alg = get_legacy_alg_type_from_keymgmt(keymgmt);
+#endif
+
     return keymgmt;
     return keymgmt;
 }
 }
 
 
@@ -275,6 +299,11 @@ int evp_keymgmt_get_number(const EVP_KEYMGMT *keymgmt)
     return keymgmt->name_id;
     return keymgmt->name_id;
 }
 }
 
 
+int evp_keymgmt_get_legacy_alg(const EVP_KEYMGMT *keymgmt)
+{
+    return keymgmt->legacy_alg;
+}
+
 const char *EVP_KEYMGMT_get0_description(const EVP_KEYMGMT *keymgmt)
 const char *EVP_KEYMGMT_get0_description(const EVP_KEYMGMT *keymgmt)
 {
 {
     return keymgmt->description;
     return keymgmt->description;

+ 3 - 2
libs/openssl/crypto/evp/legacy_sha.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -37,7 +37,8 @@ static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count)        \
 }                                                                              \
 }                                                                              \
 static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md)                      \
 static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md)                      \
 {                                                                              \
 {                                                                              \
-    return fn##_final(md, EVP_MD_CTX_get0_md_data(ctx));                       \
+    KECCAK1600_CTX *kctx = EVP_MD_CTX_get0_md_data(ctx);                       \
+    return fn##_final(kctx, md, kctx->md_size);                                \
 }
 }
 #define IMPLEMENT_LEGACY_EVP_MD_METH_SHAKE(nm, fn, tag)                        \
 #define IMPLEMENT_LEGACY_EVP_MD_METH_SHAKE(nm, fn, tag)                        \
 static int nm##_init(EVP_MD_CTX *ctx)                                          \
 static int nm##_init(EVP_MD_CTX *ctx)                                          \

+ 1 - 19
libs/openssl/crypto/evp/pmeth_lib.c

@@ -133,24 +133,6 @@ EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
     pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
     pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
     return pmeth;
     return pmeth;
 }
 }
-
-static void help_get_legacy_alg_type_from_keymgmt(const char *keytype,
-                                                  void *arg)
-{
-    int *type = arg;
-
-    if (*type == NID_undef)
-        *type = evp_pkey_name2type(keytype);
-}
-
-static int get_legacy_alg_type_from_keymgmt(const EVP_KEYMGMT *keymgmt)
-{
-    int type = NID_undef;
-
-    EVP_KEYMGMT_names_do_all(keymgmt, help_get_legacy_alg_type_from_keymgmt,
-                             &type);
-    return type;
-}
 #endif /* FIPS_MODULE */
 #endif /* FIPS_MODULE */
 
 
 int evp_pkey_ctx_state(const EVP_PKEY_CTX *ctx)
 int evp_pkey_ctx_state(const EVP_PKEY_CTX *ctx)
@@ -288,7 +270,7 @@ static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx,
          * directly.
          * directly.
          */
          */
         if (keymgmt != NULL) {
         if (keymgmt != NULL) {
-            int tmp_id = get_legacy_alg_type_from_keymgmt(keymgmt);
+            int tmp_id = evp_keymgmt_get_legacy_alg(keymgmt);
 
 
             if (tmp_id != NID_undef) {
             if (tmp_id != NID_undef) {
                 if (id == -1) {
                 if (id == -1) {

+ 24 - 1
libs/openssl/crypto/http/http_client.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright Siemens AG 2018-2020
  * Copyright Siemens AG 2018-2020
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -67,6 +67,7 @@ struct ossl_http_req_ctx_st {
     time_t max_time;            /* Maximum end time of current transfer, or 0 */
     time_t max_time;            /* Maximum end time of current transfer, or 0 */
     time_t max_total_time;      /* Maximum end time of total transfer, or 0 */
     time_t max_total_time;      /* Maximum end time of total transfer, or 0 */
     char *redirection_url;      /* Location obtained from HTTP status 301/302 */
     char *redirection_url;      /* Location obtained from HTTP status 301/302 */
+    size_t max_hdr_lines;       /* Max. number of http hdr lines, or 0 */
 };
 };
 
 
 /* HTTP states */
 /* HTTP states */
@@ -106,6 +107,7 @@ OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int buf_size)
     rctx->buf = OPENSSL_malloc(rctx->buf_size);
     rctx->buf = OPENSSL_malloc(rctx->buf_size);
     rctx->wbio = wbio;
     rctx->wbio = wbio;
     rctx->rbio = rbio;
     rctx->rbio = rbio;
+    rctx->max_hdr_lines = OSSL_HTTP_DEFAULT_MAX_RESP_HDR_LINES;
     if (rctx->buf == NULL) {
     if (rctx->buf == NULL) {
         OPENSSL_free(rctx);
         OPENSSL_free(rctx);
         return NULL;
         return NULL;
@@ -355,6 +357,16 @@ int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type
     return res;
     return res;
 }
 }
 
 
+void OSSL_HTTP_REQ_CTX_set_max_response_hdr_lines(OSSL_HTTP_REQ_CTX *rctx,
+                                                  size_t count)
+{
+    if (rctx == NULL) {
+        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
+        return;
+    }
+    rctx->max_hdr_lines = count;
+}
+
 static int add1_headers(OSSL_HTTP_REQ_CTX *rctx,
 static int add1_headers(OSSL_HTTP_REQ_CTX *rctx,
                         const STACK_OF(CONF_VALUE) *headers, const char *host)
                         const STACK_OF(CONF_VALUE) *headers, const char *host)
 {
 {
@@ -537,6 +549,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
     size_t resp_len;
     size_t resp_len;
     const unsigned char *p;
     const unsigned char *p;
     char *buf, *key, *value, *line_end = NULL;
     char *buf, *key, *value, *line_end = NULL;
+    size_t resp_hdr_lines = 0;
 
 
     if (rctx == NULL) {
     if (rctx == NULL) {
         ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
         ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
@@ -682,6 +695,14 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
             return 0;
             return 0;
         }
         }
 
 
+        resp_hdr_lines++;
+        if (rctx->max_hdr_lines != 0 && rctx->max_hdr_lines < resp_hdr_lines) {
+            ERR_raise(ERR_LIB_HTTP, HTTP_R_RESPONSE_TOO_MANY_HDRLINES);
+            OSSL_TRACE(HTTP, "Received too many headers\n");
+            rctx->state = OHS_ERROR;
+            return 0;
+        }
+
         /* Don't allow excessive lines */
         /* Don't allow excessive lines */
         if (n == rctx->buf_size) {
         if (n == rctx->buf_size) {
             ERR_raise(ERR_LIB_HTTP, HTTP_R_RESPONSE_LINE_TOO_LONG);
             ERR_raise(ERR_LIB_HTTP, HTTP_R_RESPONSE_LINE_TOO_LONG);
@@ -786,6 +807,8 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
         if (OSSL_TRACE_ENABLED(HTTP))
         if (OSSL_TRACE_ENABLED(HTTP))
             OSSL_TRACE(HTTP, "]\n");
             OSSL_TRACE(HTTP, "]\n");
 
 
+        resp_hdr_lines = 0;
+
         if (rctx->keep_alive != 0 /* do not let server initiate keep_alive */
         if (rctx->keep_alive != 0 /* do not let server initiate keep_alive */
                 && !found_keep_alive /* otherwise there is no change */) {
                 && !found_keep_alive /* otherwise there is no change */) {
             if (rctx->keep_alive == 2) {
             if (rctx->keep_alive == 2) {

+ 12 - 5
libs/openssl/crypto/http/http_err.c

@@ -1,6 +1,6 @@
 /*
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -12,7 +12,9 @@
 #include <openssl/httperr.h>
 #include <openssl/httperr.h>
 #include "crypto/httperr.h"
 #include "crypto/httperr.h"
 
 
-#ifndef OPENSSL_NO_ERR
+#ifndef OPENSSL_NO_HTTP
+
+# ifndef OPENSSL_NO_ERR
 
 
 static const ERR_STRING_DATA HTTP_str_reasons[] = {
 static const ERR_STRING_DATA HTTP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN),
     {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN),
@@ -55,6 +57,8 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = {
     "response line too long"},
     "response line too long"},
     {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_PARSE_ERROR),
     {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_PARSE_ERROR),
     "response parse error"},
     "response parse error"},
+    {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_TOO_MANY_HDRLINES),
+    "response too many hdrlines"},
     {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RETRY_TIMEOUT), "retry timeout"},
     {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RETRY_TIMEOUT), "retry timeout"},
     {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SERVER_CANCELED_CONNECTION),
     {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SERVER_CANCELED_CONNECTION),
     "server canceled connection"},
     "server canceled connection"},
@@ -70,13 +74,16 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = {
     {0, NULL}
     {0, NULL}
 };
 };
 
 
-#endif
+# endif
 
 
 int ossl_err_load_HTTP_strings(void)
 int ossl_err_load_HTTP_strings(void)
 {
 {
-#ifndef OPENSSL_NO_ERR
+# ifndef OPENSSL_NO_ERR
     if (ERR_reason_error_string(HTTP_str_reasons[0].error) == NULL)
     if (ERR_reason_error_string(HTTP_str_reasons[0].error) == NULL)
         ERR_load_strings_const(HTTP_str_reasons);
         ERR_load_strings_const(HTTP_str_reasons);
-#endif
+# endif
     return 1;
     return 1;
 }
 }
+#else
+NON_EMPTY_TRANSLATION_UNIT
+#endif

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

@@ -27,7 +27,7 @@
  *
  *
  * The FIPS provider tells libcrypto about which threads it is interested in
  * The FIPS provider tells libcrypto about which threads it is interested in
  * by calling "c_thread_start" which is a function pointer created during
  * by calling "c_thread_start" which is a function pointer created during
- * provider initialisation (i.e. OSSL_init_provider).
+ * provider initialisation (i.e. OSSL_provider_init).
  */
  */
 extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
 extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
 #endif
 #endif

+ 1 - 1
libs/openssl/crypto/lhash/lh_stats.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 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
  * 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
  * this file except in compliance with the License.  You can obtain a copy

+ 56 - 12
libs/openssl/crypto/lhash/lhash.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -44,6 +44,22 @@ static int expand(OPENSSL_LHASH *lh);
 static void contract(OPENSSL_LHASH *lh);
 static void contract(OPENSSL_LHASH *lh);
 static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, const void *data, unsigned long *rhash);
 static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, const void *data, unsigned long *rhash);
 
 
+OPENSSL_LHASH *OPENSSL_LH_set_thunks(OPENSSL_LHASH *lh,
+                                     OPENSSL_LH_HASHFUNCTHUNK hw,
+                                     OPENSSL_LH_COMPFUNCTHUNK cw,
+                                     OPENSSL_LH_DOALL_FUNC_THUNK daw,
+                                     OPENSSL_LH_DOALL_FUNCARG_THUNK daaw)
+{
+
+    if (lh == NULL)
+        return NULL;
+    lh->compw = cw;
+    lh->hashw = hw;
+    lh->daw = daw;
+    lh->daaw = daaw;
+    return lh;
+}
+
 OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c)
 OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c)
 {
 {
     OPENSSL_LHASH *ret;
     OPENSSL_LHASH *ret;
@@ -168,8 +184,11 @@ void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data)
 }
 }
 
 
 static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
 static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
+                          OPENSSL_LH_DOALL_FUNC_THUNK wfunc,
                           OPENSSL_LH_DOALL_FUNC func,
                           OPENSSL_LH_DOALL_FUNC func,
-                          OPENSSL_LH_DOALL_FUNCARG func_arg, void *arg)
+                          OPENSSL_LH_DOALL_FUNCARG func_arg,
+                          OPENSSL_LH_DOALL_FUNCARG_THUNK wfunc_arg,
+                          void *arg)
 {
 {
     int i;
     int i;
     OPENSSL_LH_NODE *a, *n;
     OPENSSL_LH_NODE *a, *n;
@@ -186,9 +205,9 @@ static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
         while (a != NULL) {
         while (a != NULL) {
             n = a->next;
             n = a->next;
             if (use_arg)
             if (use_arg)
-                func_arg(a->data, arg);
+                wfunc_arg(a->data, arg, func_arg);
             else
             else
-                func(a->data);
+                wfunc(a->data, func);
             a = n;
             a = n;
         }
         }
     }
     }
@@ -196,12 +215,29 @@ static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
 
 
 void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func)
 void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func)
 {
 {
-    doall_util_fn(lh, 0, func, (OPENSSL_LH_DOALL_FUNCARG)0, NULL);
+    if (lh == NULL)
+        return;
+
+    doall_util_fn(lh, 0, lh->daw, func, (OPENSSL_LH_DOALL_FUNCARG)NULL,
+                  (OPENSSL_LH_DOALL_FUNCARG_THUNK)NULL, NULL);
 }
 }
 
 
-void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg)
+void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh,
+                          OPENSSL_LH_DOALL_FUNCARG func, void *arg)
 {
 {
-    doall_util_fn(lh, 1, (OPENSSL_LH_DOALL_FUNC)0, func, arg);
+    if (lh == NULL)
+        return;
+
+    doall_util_fn(lh, 1, (OPENSSL_LH_DOALL_FUNC_THUNK)NULL,
+                  (OPENSSL_LH_DOALL_FUNC)NULL, func, lh->daaw, arg);
+}
+
+void OPENSSL_LH_doall_arg_thunk(OPENSSL_LHASH *lh,
+                                OPENSSL_LH_DOALL_FUNCARG_THUNK daaw,
+                                OPENSSL_LH_DOALL_FUNCARG fn, void *arg)
+{
+    doall_util_fn(lh, 1, (OPENSSL_LH_DOALL_FUNC_THUNK)NULL,
+                  (OPENSSL_LH_DOALL_FUNC)NULL, fn, daaw, arg);
 }
 }
 
 
 static int expand(OPENSSL_LHASH *lh)
 static int expand(OPENSSL_LHASH *lh)
@@ -286,24 +322,32 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
 {
 {
     OPENSSL_LH_NODE **ret, *n1;
     OPENSSL_LH_NODE **ret, *n1;
     unsigned long hash, nn;
     unsigned long hash, nn;
-    OPENSSL_LH_COMPFUNC cf;
 
 
-    hash = (*(lh->hash)) (data);
+    if (lh->hashw != NULL)
+        hash = lh->hashw(data, lh->hash);
+    else
+        hash = lh->hash(data);
+
     *rhash = hash;
     *rhash = hash;
 
 
     nn = hash % lh->pmax;
     nn = hash % lh->pmax;
     if (nn < lh->p)
     if (nn < lh->p)
         nn = hash % lh->num_alloc_nodes;
         nn = hash % lh->num_alloc_nodes;
 
 
-    cf = lh->comp;
     ret = &(lh->b[(int)nn]);
     ret = &(lh->b[(int)nn]);
     for (n1 = *ret; n1 != NULL; n1 = n1->next) {
     for (n1 = *ret; n1 != NULL; n1 = n1->next) {
         if (n1->hash != hash) {
         if (n1->hash != hash) {
             ret = &(n1->next);
             ret = &(n1->next);
             continue;
             continue;
         }
         }
-        if (cf(n1->data, data) == 0)
-            break;
+
+        if (lh->compw != NULL) {
+            if (lh->compw(n1->data, data, lh->comp) == 0)
+                break;
+        } else {
+            if (lh->comp(n1->data, data) == 0)
+                break;
+        }
         ret = &(n1->next);
         ret = &(n1->next);
     }
     }
     return ret;
     return ret;

+ 5 - 1
libs/openssl/crypto/lhash/lhash_local.h

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -20,6 +20,10 @@ struct lhash_st {
     OPENSSL_LH_NODE **b;
     OPENSSL_LH_NODE **b;
     OPENSSL_LH_COMPFUNC comp;
     OPENSSL_LH_COMPFUNC comp;
     OPENSSL_LH_HASHFUNC hash;
     OPENSSL_LH_HASHFUNC hash;
+    OPENSSL_LH_HASHFUNCTHUNK hashw;
+    OPENSSL_LH_COMPFUNCTHUNK compw;
+    OPENSSL_LH_DOALL_FUNC_THUNK daw;
+    OPENSSL_LH_DOALL_FUNCARG_THUNK daaw;
     unsigned int num_nodes;
     unsigned int num_nodes;
     unsigned int num_alloc_nodes;
     unsigned int num_alloc_nodes;
     unsigned int p;
     unsigned int p;

+ 2 - 2
libs/openssl/crypto/loongarch64cpuid.pl

@@ -101,8 +101,8 @@ $code.=<<___;
 .globl OPENSSL_rdtsc
 .globl OPENSSL_rdtsc
 .type   OPENSSL_rdtsc,\@function
 .type   OPENSSL_rdtsc,\@function
 OPENSSL_rdtsc:
 OPENSSL_rdtsc:
-    move    $a0,$zero
-    jr      $ra
+    rdtimel.w $a0,$zero
+    jr        $ra
 ___
 ___
 }
 }
 
 

+ 297 - 0
libs/openssl/crypto/md5/asm/md5-loongarch64.pl

@@ -0,0 +1,297 @@
+#! /usr/bin/env perl
+# Author: Min Zhou <[email protected]>
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (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
+
+# Reference to crypto/md5/asm/md5-x86_64.pl
+# MD5 optimized for LoongArch.
+
+use strict;
+
+my $code;
+
+my ($zero,$ra,$tp,$sp,$fp)=map("\$r$_",(0..3,22));
+my ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$r$_",(4..11));
+my ($t0,$t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$x)=map("\$r$_",(12..21));
+
+my $output;
+for (@ARGV) {	$output=$_ if (/\w[\w\-]*\.\w+$/);	}
+open STDOUT,">$output";
+
+# round1_step() does:
+#   dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s)
+#   $t1 = y ^ z
+#   $t2 = dst + X[k_next]
+sub round1_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    my $T_i_h = ($T_i & 0xfffff000) >> 12;
+    my $T_i_l = $T_i & 0xfff;
+
+# In LoongArch we have to use two instructions of lu12i.w and ori to load a
+# 32-bit immediate into a general register. Meanwhile, the instruction lu12i.w
+# treats the 20-bit immediate as a signed number. So if the T_i_h is greater
+# than or equal to (1<<19), we need provide lu12i.w a corresponding negative
+# number whose complement equals to the sign extension of T_i_h.
+
+# The details of the instruction lu12i.w can be found as following:
+# https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_lu12i_w_lu32i_d_lu52i_d
+
+    $T_i_h = -((1<<32) - (0xfff00000 | $T_i_h)) if ($T_i_h >= (1<<19));
+
+    $code .= "	ld.w	$t0,$a1,0		/* (NEXT STEP) X[0] */\n" if ($pos == -1);
+    $code .= "	xor	$t1,$y,$z		/* y ^ z */\n" if ($pos == -1);
+    $code .= "	add.w	$t2,$dst,$t0		/* dst + X[k] */\n" if ($pos == -1);
+    $code .= <<EOF;
+	lu12i.w	$t8,$T_i_h			/* load bits [31:12] of constant */
+	and     $t1,$x,$t1			/* x & ... */
+	ori	$t8,$t8,$T_i_l			/* load bits [11:0] of constant */
+	xor     $t1,$z,$t1			/* z ^ ... */
+	add.w   $t7,$t2,$t8			/* dst + X[k] + Const */
+	ld.w	$t0,$a1,$k_next*4		/* (NEXT STEP) X[$k_next] */
+	add.w	$dst,$t7,$t1			/* dst += ... */
+	add.w	$t2,$z,$t0			/* (NEXT STEP) dst + X[$k_next] */
+EOF
+
+    $code .= "	rotri.w	$dst,$dst,32-$s		/* dst <<< s */\n";
+    if ($pos != 1) {
+        $code .= "	xor	$t1,$x,$y	/* (NEXT STEP) y ^ z */\n";
+    } else {
+        $code .= "	move	$t0,$a7		/* (NEXT ROUND) $t0 = z' (copy of z) */\n";
+        $code .= "	nor	$t1,$zero,$a7	/* (NEXT ROUND) $t1 = not z' (copy of not z) */\n";
+    }
+    $code .= "	add.w   $dst,$dst,$x		/* dst += x */\n";
+}
+
+# round2_step() does:
+#   dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s)
+#   $t0 = z' (copy of z for the next step)
+#   $t1 = not z' (copy of not z for the next step)
+#   $t2 = dst + X[k_next]
+sub round2_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    my $T_i_h = ($T_i & 0xfffff000) >> 12;
+    my $T_i_l = $T_i & 0xfff;
+    $T_i_h = -((1<<32) - (0xfff00000 | $T_i_h)) if ($T_i_h >= (1<<19));
+
+    $code .= <<EOF;
+	lu12i.w	$t8,$T_i_h			/* load bits [31:12] of Constant */
+	and	$t0,$x,$t0			/* x & z */
+	ori	$t8,$t8,$T_i_l			/* load bits [11:0] of Constant */
+	and	$t1,$y,$t1			/* y & (not z) */
+	add.w	$t7,$t2,$t8			/* dst + X[k] + Const */
+	or	$t1,$t0,$t1			/* (y & (not z)) | (x & z) */
+	ld.w	$t0,$a1,$k_next*4		/* (NEXT STEP) X[$k_next] */
+	add.w	$dst,$t7,$t1			/* dst += ... */
+	add.w	$t2,$z,$t0			/* (NEXT STEP) dst + X[$k_next] */
+EOF
+
+    $code .= "	rotri.w $dst,$dst,32-$s		/* dst <<< s */\n";
+    if ($pos != 1) {
+        $code .= "	move	$t0,$y		/* (NEXT STEP) z' = $y */\n";
+        $code .= "	nor	$t1,$zero,$y	/* (NEXT STEP) not z' = not $y */\n";
+    } else {
+        $code .= "	xor	$t1,$a6,$a7	/* (NEXT ROUND) $t1 = y ^ z */\n";
+    }
+    $code .= "	add.w	$dst,$dst,$x		/* dst += x */\n";
+}
+
+# round3_step() does:
+#   dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s)
+#   $t1 = y ^ z
+#   $t2 = dst + X[k_next]
+sub round3_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    my $T_i_h = ($T_i & 0xfffff000) >> 12;
+    my $T_i_l = $T_i & 0xfff;
+    $T_i_h = -((1<<32) - (0xfff00000 | $T_i_h)) if ($T_i_h >= (1<<19));
+
+    $code .= <<EOF;
+	lu12i.w	$t8,$T_i_h			/* load bits [31:12] of Constant */
+	xor	$t1,$x,$t1			/* x ^ ... */
+	ori	$t8,$t8,$T_i_l			/* load bits [11:0] of Constant */
+	add.w	$t7,$t2,$t8			/* dst + X[k] + Const */
+	ld.w	$t0,$a1,$k_next*4		/* (NEXT STEP) X[$k_next] */
+	add.w	$dst,$t7,$t1			/* dst += ... */
+	add.w	$t2,$z,$t0			/* (NEXT STEP) dst + X[$k_next] */
+EOF
+
+    $code .= "	rotri.w $dst,$dst,32-$s		/* dst <<< s */\n";
+    if ($pos != 1) {
+	$code .= "	xor	$t1,$x,$y	/* (NEXT STEP) y ^ z */\n";
+    } else {
+        $code .= "	nor	$t1,$zero,$a7	/* (NEXT ROUND) $t1 = not z */\n";
+    }
+    $code .= "	add.w	$dst,$dst,$x		/* dst += x */\n";
+}
+
+# round4_step() does:
+#   dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s)
+#   $t1 = not z' (copy of not z for the next step)
+#   $t2 = dst + X[k_next]
+sub round4_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    my $T_i_h = ($T_i & 0xfffff000) >> 12;
+    my $T_i_l = $T_i & 0xfff;
+    $T_i_h = -((1<<32) - (0xfff00000 | $T_i_h)) if ($T_i_h >= (1<<19));
+
+    $code .= <<EOF;
+	lu12i.w	$t8,$T_i_h			/* load bits [31:12] of Constant */
+	or	$t1,$x,$t1			/* x | ... */
+	ori	$t8,$t8,$T_i_l			/* load bits [11:0] of Constant */
+	xor	$t1,$y,$t1			/* y ^ ... */
+	add.w	$t7,$t2,$t8			/* dst + X[k] + Const */
+EOF
+
+    if ($pos != 1) {
+        $code .= "	ld.w	$t0,$a1,$k_next*4		/* (NEXT STEP) X[$k_next] */\n";
+        $code .= "	add.w	$dst,$t7,$t1			/* dst += ... */\n";
+        $code .= "	add.w	$t2,$z,$t0			/* (NEXT STEP) dst + X[$k_next] */\n";
+        $code .= "	rotri.w $dst,$dst,32-$s			/* dst <<< s */\n";
+        $code .= "	nor	$t1,$zero,$y			/* (NEXT STEP) not z' = not $y */\n";
+        $code .= "	add.w	$dst,$dst,$x			/* dst += x */\n";
+    } else {
+        $code .= "	add.w	$a4,$t3,$a4			/* (NEXT LOOP) add old value of A */\n";
+        $code .= "	add.w	$dst,$t7,$t1			/* dst += ... */\n";
+        $code .= "	add.w	$a7,$t6,$a7			/* (NEXT LOOP) add old value of D */\n";
+        $code .= "	rotri.w $dst,$dst,32-$s			/* dst <<< s */\n";
+        $code .= "	addi.d	$a1,$a1,64			/* (NEXT LOOP) ptr += 64 */\n";
+        $code .= "	add.w	$dst,$dst,$x			/* dst += x */\n";
+    }
+}
+
+$code .= <<EOF;
+.text
+
+.globl ossl_md5_block_asm_data_order
+.type ossl_md5_block_asm_data_order function
+ossl_md5_block_asm_data_order:
+	# $a0 = arg #1 (ctx, MD5_CTX pointer)
+	# $a1 = arg #2 (ptr, data pointer)
+	# $a2 = arg #3 (nbr, number of 16-word blocks to process)
+	beqz	$a2,.Lend		# cmp nbr with 0, jmp if nbr == 0
+
+	# ptr is '$a1'
+	# end is '$a3'
+	slli.d	$t0,$a2,6
+	add.d	$a3,$a1,$t0
+
+	# A is '$a4'
+	# B is '$a5'
+	# C is '$a6'
+	# D is '$a7'
+	ld.w	$a4,$a0,0	# a4 = ctx->A
+	ld.w	$a5,$a0,4	# a5 = ctx->B
+	ld.w	$a6,$a0,8	# a6 = ctx->C
+	ld.w	$a7,$a0,12	# a7 = ctx->D
+
+# BEGIN of loop over 16-word blocks
+.align 6
+.Lloop:
+	# save old values of A, B, C, D
+	move	$t3,$a4
+	move	$t4,$a5
+	move	$t5,$a6
+	move	$t6,$a7
+
+	preld	0,$a1,0
+	preld	0,$a1,64
+EOF
+
+round1_step(-1, $a4, $a5, $a6, $a7, '1', 0xd76aa478, '7');
+round1_step(0, $a7, $a4, $a5, $a6, '2', 0xe8c7b756, '12');
+round1_step(0, $a6, $a7, $a4, $a5, '3', 0x242070db, '17');
+round1_step(0, $a5, $a6, $a7, $a4, '4', 0xc1bdceee, '22');
+round1_step(0, $a4, $a5, $a6, $a7, '5', 0xf57c0faf, '7');
+round1_step(0, $a7, $a4, $a5, $a6, '6', 0x4787c62a, '12');
+round1_step(0, $a6, $a7, $a4, $a5, '7', 0xa8304613, '17');
+round1_step(0, $a5, $a6, $a7, $a4, '8', 0xfd469501, '22');
+round1_step(0, $a4, $a5, $a6, $a7, '9', 0x698098d8, '7');
+round1_step(0, $a7, $a4, $a5, $a6, '10', 0x8b44f7af, '12');
+round1_step(0, $a6, $a7, $a4, $a5, '11', 0xffff5bb1, '17');
+round1_step(0, $a5, $a6, $a7, $a4, '12', 0x895cd7be, '22');
+round1_step(0, $a4, $a5, $a6, $a7, '13', 0x6b901122, '7');
+round1_step(0, $a7, $a4, $a5, $a6, '14', 0xfd987193, '12');
+round1_step(0, $a6, $a7, $a4, $a5, '15', 0xa679438e, '17');
+round1_step(1, $a5, $a6, $a7, $a4, '1', 0x49b40821, '22');
+
+round2_step(-1, $a4, $a5, $a6, $a7, '6', 0xf61e2562, '5');
+round2_step(0, $a7, $a4, $a5, $a6, '11', 0xc040b340, '9');
+round2_step(0, $a6, $a7, $a4, $a5, '0', 0x265e5a51, '14');
+round2_step(0, $a5, $a6, $a7, $a4, '5', 0xe9b6c7aa, '20');
+round2_step(0, $a4, $a5, $a6, $a7, '10', 0xd62f105d, '5');
+round2_step(0, $a7, $a4, $a5, $a6, '15', 0x2441453, '9');
+round2_step(0, $a6, $a7, $a4, $a5, '4', 0xd8a1e681, '14');
+round2_step(0, $a5, $a6, $a7, $a4, '9', 0xe7d3fbc8, '20');
+round2_step(0, $a4, $a5, $a6, $a7, '14', 0x21e1cde6, '5');
+round2_step(0, $a7, $a4, $a5, $a6, '3', 0xc33707d6, '9');
+round2_step(0, $a6, $a7, $a4, $a5, '8', 0xf4d50d87, '14');
+round2_step(0, $a5, $a6, $a7, $a4, '13', 0x455a14ed, '20');
+round2_step(0, $a4, $a5, $a6, $a7, '2', 0xa9e3e905, '5');
+round2_step(0, $a7, $a4, $a5, $a6, '7', 0xfcefa3f8, '9');
+round2_step(0, $a6, $a7, $a4, $a5, '12', 0x676f02d9, '14');
+round2_step(1, $a5, $a6, $a7, $a4, '5', 0x8d2a4c8a, '20');
+
+round3_step(-1, $a4, $a5, $a6, $a7, '8', 0xfffa3942, '4');
+round3_step(0, $a7, $a4, $a5, $a6, '11', 0x8771f681, '11');
+round3_step(0, $a6, $a7, $a4, $a5, '14', 0x6d9d6122, '16');
+round3_step(0, $a5, $a6, $a7, $a4, '1', 0xfde5380c, '23');
+round3_step(0, $a4, $a5, $a6, $a7, '4', 0xa4beea44, '4');
+round3_step(0, $a7, $a4, $a5, $a6, '7', 0x4bdecfa9, '11');
+round3_step(0, $a6, $a7, $a4, $a5, '10', 0xf6bb4b60, '16');
+round3_step(0, $a5, $a6, $a7, $a4, '13', 0xbebfbc70, '23');
+round3_step(0, $a4, $a5, $a6, $a7, '0', 0x289b7ec6, '4');
+round3_step(0, $a7, $a4, $a5, $a6, '3', 0xeaa127fa, '11');
+round3_step(0, $a6, $a7, $a4, $a5, '6', 0xd4ef3085, '16');
+round3_step(0, $a5, $a6, $a7, $a4, '9', 0x4881d05, '23');
+round3_step(0, $a4, $a5, $a6, $a7, '12', 0xd9d4d039, '4');
+round3_step(0, $a7, $a4, $a5, $a6, '15', 0xe6db99e5, '11');
+round3_step(0, $a6, $a7, $a4, $a5, '2', 0x1fa27cf8, '16');
+round3_step(1, $a5, $a6, $a7, $a4, '0', 0xc4ac5665, '23');
+
+round4_step(-1, $a4, $a5, $a6, $a7, '7', 0xf4292244, '6');
+round4_step(0, $a7, $a4, $a5, $a6, '14', 0x432aff97, '10');
+round4_step(0, $a6, $a7, $a4, $a5, '5', 0xab9423a7, '15');
+round4_step(0, $a5, $a6, $a7, $a4, '12', 0xfc93a039, '21');
+round4_step(0, $a4, $a5, $a6, $a7, '3', 0x655b59c3, '6');
+round4_step(0, $a7, $a4, $a5, $a6, '10', 0x8f0ccc92, '10');
+round4_step(0, $a6, $a7, $a4, $a5, '1', 0xffeff47d, '15');
+round4_step(0, $a5, $a6, $a7, $a4, '8', 0x85845dd1, '21');
+round4_step(0, $a4, $a5, $a6, $a7, '15', 0x6fa87e4f, '6');
+round4_step(0, $a7, $a4, $a5, $a6, '6', 0xfe2ce6e0, '10');
+round4_step(0, $a6, $a7, $a4, $a5, '13', 0xa3014314, '15');
+round4_step(0, $a5, $a6, $a7, $a4, '4', 0x4e0811a1, '21');
+round4_step(0, $a4, $a5, $a6, $a7, '11', 0xf7537e82, '6');
+round4_step(0, $a7, $a4, $a5, $a6, '2', 0xbd3af235, '10');
+round4_step(0, $a6, $a7, $a4, $a5, '9', 0x2ad7d2bb, '15');
+round4_step(1, $a5, $a6, $a7, $a4, '0', 0xeb86d391, '21');
+
+$code .= <<EOF;
+	# add old values of B, C
+	add.w	$a5,$t4,$a5
+	add.w	$a6,$t5,$a6
+
+	bltu	$a1,$a3,.Lloop	# jmp if ptr < end
+
+	st.w	$a4,$a0,0	# ctx->A = A
+	st.w	$a5,$a0,4	# ctx->B = B
+	st.w	$a6,$a0,8	# ctx->C = C
+	st.w	$a7,$a0,12	# ctx->D = D
+
+.Lend:
+	jr	$ra
+.size ossl_md5_block_asm_data_order,.-ossl_md5_block_asm_data_order
+EOF
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+print $code;
+
+close STDOUT;

+ 4 - 0
libs/openssl/crypto/md5/build.info

@@ -5,6 +5,7 @@ IF[{- !$disabled{asm} -}]
   $MD5ASM_x86=md5-586.S
   $MD5ASM_x86=md5-586.S
   $MD5ASM_x86_64=md5-x86_64.s
   $MD5ASM_x86_64=md5-x86_64.s
   $MD5ASM_aarch64=md5-aarch64.S
   $MD5ASM_aarch64=md5-aarch64.S
+  $MD5ASM_loongarch64=md5-loongarch64.S
   $MD5ASM_sparcv9=md5-sparcv9.S
   $MD5ASM_sparcv9=md5-sparcv9.S
 
 
   # Now that we have defined all the arch specific variables, use the
   # Now that we have defined all the arch specific variables, use the
@@ -39,5 +40,8 @@ GENERATE[md5-x86_64.s]=asm/md5-x86_64.pl
 GENERATE[md5-aarch64.S]=asm/md5-aarch64.pl
 GENERATE[md5-aarch64.S]=asm/md5-aarch64.pl
 INCLUDE[md5-aarch64.o]=..
 INCLUDE[md5-aarch64.o]=..
 
 
+GENERATE[md5-loongarch64.S]=asm/md5-loongarch64.pl
+INCLUDE[md5-loongarch64.o]=..
+
 GENERATE[md5-sparcv9.S]=asm/md5-sparcv9.pl
 GENERATE[md5-sparcv9.S]=asm/md5-sparcv9.pl
 INCLUDE[md5-sparcv9.o]=..
 INCLUDE[md5-sparcv9.o]=..

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно