Browse Source

Merge branch 'thirdparty_dev' into dev

# Conflicts:

#	libs/openssl/include/openssl/bio.h
#	libs/openssl/include/openssl/cmp.h
#	libs/openssl/include/openssl/err.h
#	libs/openssl/include/openssl/lhash.h
#	libs/openssl/include/openssl/pkcs7.h
#	libs/openssl/include/openssl/ssl.h
#	libs/openssl/include/openssl/x509_vfy.h

.in

Source commit: 9c0c77794e087c6046e339af292ca0456e7edf25
Martin Prikryl 1 year ago
parent
commit
f457be95a8
100 changed files with 2985 additions and 545 deletions
  1. 12 2
      libs/openssl/INSTALL.md
  2. 3 5
      libs/openssl/crypto/asn1/a_time.c
  3. 5 1
      libs/openssl/crypto/asn1/asn1_err.c
  4. 9 1
      libs/openssl/crypto/asn1/tasn_dec.c
  5. 3 2
      libs/openssl/crypto/bio/bio_dump.c
  6. 1 1
      libs/openssl/crypto/bio/bio_lib.c
  7. 3 1
      libs/openssl/crypto/bio/bio_meth.c
  8. 0 3
      libs/openssl/crypto/bio/bio_sock.c
  9. 1 1
      libs/openssl/crypto/bio/bss_dgram.c
  10. 1 1
      libs/openssl/crypto/bn/bn_gcd.c
  11. 1 1
      libs/openssl/crypto/bn/bn_mod.c
  12. 7 3
      libs/openssl/crypto/chacha/chacha_enc.c
  13. 9 5
      libs/openssl/crypto/cmac/cmac.c
  14. 8 1
      libs/openssl/crypto/cmp/cmp_err.c
  15. 10 1
      libs/openssl/crypto/cmp/cmp_local.h
  16. 1 1
      libs/openssl/crypto/cms/cms_enc.c
  17. 9 1
      libs/openssl/crypto/cms/cms_pwri.c
  18. 1 1
      libs/openssl/crypto/conf/conf_lib.c
  19. 92 47
      libs/openssl/crypto/conf/conf_mod.c
  20. 1 1
      libs/openssl/crypto/conf/conf_sap.c
  21. 2 2
      libs/openssl/crypto/dh/dh_check.c
  22. 1 1
      libs/openssl/crypto/dsa/dsa_check.c
  23. 2 2
      libs/openssl/crypto/dso/dso_dl.c
  24. 2 2
      libs/openssl/crypto/dso/dso_dlfcn.c
  25. 1 1
      libs/openssl/crypto/ec/curve448/ed448.h
  26. 13 0
      libs/openssl/crypto/err/err_mark.c
  27. 5 1
      libs/openssl/crypto/evp/bio_enc.c
  28. 35 2
      libs/openssl/crypto/evp/digest.c
  29. 13 13
      libs/openssl/crypto/evp/evp_enc.c
  30. 1 1
      libs/openssl/crypto/evp/evp_fetch.c
  31. 2 2
      libs/openssl/crypto/evp/evp_key.c
  32. 27 9
      libs/openssl/crypto/evp/evp_lib.c
  33. 3 1
      libs/openssl/crypto/evp/evp_local.h
  34. 30 1
      libs/openssl/crypto/evp/keymgmt_meth.c
  35. 3 2
      libs/openssl/crypto/evp/legacy_sha.c
  36. 1 19
      libs/openssl/crypto/evp/pmeth_lib.c
  37. 24 1
      libs/openssl/crypto/http/http_client.c
  38. 12 5
      libs/openssl/crypto/http/http_err.c
  39. 1 1
      libs/openssl/crypto/initthread.c
  40. 1 1
      libs/openssl/crypto/lhash/lh_stats.c
  41. 56 12
      libs/openssl/crypto/lhash/lhash.c
  42. 5 1
      libs/openssl/crypto/lhash/lhash_local.h
  43. 2 1
      libs/openssl/crypto/md5/md5_local.h
  44. 25 3
      libs/openssl/crypto/modes/gcm128.c
  45. 11 6
      libs/openssl/crypto/objects/obj_dat.h
  46. 1 1
      libs/openssl/crypto/objects/obj_xref.h
  47. 1 17
      libs/openssl/crypto/param_build.c
  48. 1 1
      libs/openssl/crypto/param_build_set.c
  49. 10 2
      libs/openssl/crypto/pkcs12/p12_decr.c
  50. 1 1
      libs/openssl/crypto/pkcs7/pk7_attr.c
  51. 2 3
      libs/openssl/crypto/pkcs7/pk7_smime.c
  52. 48 7
      libs/openssl/crypto/provider_conf.c
  53. 1 1
      libs/openssl/crypto/rand/rand_pool.c
  54. 3 3
      libs/openssl/crypto/rand/rand_uniform.c
  55. 144 14
      libs/openssl/crypto/rsa/rsa_backend.c
  56. 255 76
      libs/openssl/crypto/rsa/rsa_gen.c
  57. 29 7
      libs/openssl/crypto/rsa/rsa_lib.c
  58. 5 1
      libs/openssl/crypto/rsa/rsa_local.h
  59. 38 33
      libs/openssl/crypto/rsa/rsa_sp800_56b_gen.c
  60. 13 6
      libs/openssl/crypto/sha/keccak1600.c
  61. 10 2
      libs/openssl/crypto/sha/sha256.c
  62. 96 4
      libs/openssl/crypto/sha/sha3.c
  63. 9 1
      libs/openssl/crypto/sha/sha512.c
  64. 2 1
      libs/openssl/crypto/sleep.c
  65. 4 17
      libs/openssl/crypto/sm2/sm2_crypt.c
  66. 6 1
      libs/openssl/crypto/sm3/sm3_local.h
  67. 2 2
      libs/openssl/crypto/stack/stack.c
  68. 358 3
      libs/openssl/crypto/threads_win.c
  69. 1 1
      libs/openssl/crypto/x509/t_req.c
  70. 1 1
      libs/openssl/crypto/x509/t_x509.c
  71. 4 0
      libs/openssl/crypto/x509/v3_addr.c
  72. 0 3
      libs/openssl/crypto/x509/v3_ist.c
  73. 31 1
      libs/openssl/crypto/x509/x509_lu.c
  74. 80 6
      libs/openssl/include/crypto/aes_platform.h
  75. 6 0
      libs/openssl/include/crypto/chacha.h
  76. 5 0
      libs/openssl/include/crypto/dsa.h
  77. 3 1
      libs/openssl/include/crypto/evp.h
  78. 4 1
      libs/openssl/include/crypto/httperr.h
  79. 10 0
      libs/openssl/include/crypto/riscv_arch.def
  80. 15 0
      libs/openssl/include/crypto/riscv_arch.h
  81. 4 4
      libs/openssl/include/crypto/rsa.h
  82. 13 1
      libs/openssl/include/crypto/sm4_platform.h
  83. 20 6
      libs/openssl/include/internal/common.h
  84. 226 0
      libs/openssl/include/internal/json_enc.h
  85. 36 2
      libs/openssl/include/internal/list.h
  86. 131 0
      libs/openssl/include/internal/qlog.h
  87. 56 0
      libs/openssl/include/internal/qlog_event_helpers.h
  88. 15 0
      libs/openssl/include/internal/qlog_events.h
  89. 1 2
      libs/openssl/include/internal/quic_ackm.h
  90. 3 4
      libs/openssl/include/internal/quic_cc.h
  91. 1 1
      libs/openssl/include/internal/quic_cfq.h
  92. 63 42
      libs/openssl/include/internal/quic_channel.h
  93. 26 86
      libs/openssl/include/internal/quic_demux.h
  94. 84 0
      libs/openssl/include/internal/quic_engine.h
  95. 10 4
      libs/openssl/include/internal/quic_fc.h
  96. 257 0
      libs/openssl/include/internal/quic_lcidm.h
  97. 142 0
      libs/openssl/include/internal/quic_port.h
  98. 43 0
      libs/openssl/include/internal/quic_predef.h
  99. 185 0
      libs/openssl/include/internal/quic_rcidm.h
  100. 15 5
      libs/openssl/include/internal/quic_reactor.h

+ 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 the DOS platform with DJGPP](NOTES-DJGPP.md)
  * [Notes for the OpenVMS platform](NOTES-VMS.md)
+ * [Notes for the HPE NonStop platform](NOTES-NONSTOP.md)
  * [Notes on Perl](NOTES-PERL.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
 OpenSSL for production use.
 
-### Unix / Linux / macOS
+### Unix / Linux / macOS / NonStop
 
     $ ./Configure
     $ 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
 [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
 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
 circumstances. This option disables the atexit registration of OPENSSL_cleanup.
+By default, NonStop configurations use `no-atexit`.
 
 ### no-autoalginit
 
@@ -1082,6 +1084,14 @@ when needed.
 
 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
 
 In 32-bit x86 builds, use the 80386 instruction set only in assembly modules

+ 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 mdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
     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;
 #if defined(CHARSET_EBCDIC)
     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
      */
     if (d->type == V_ASN1_UTCTIME) {
+        min_l = 13;
         if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
-            min_l = 13;
             strict = 1;
         }
     } else if (d->type == V_ASN1_GENERALIZEDTIME) {
         end = 7;
         btz = 6;
+        min_l = 15;
         if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
-            min_l = 15;
             strict = 1;
-        } else {
-            min_l = 13;
         }
     } else {
         return 0;

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

@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-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
@@ -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_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_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),
     "unsupported public key 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),
     "wrong integer 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
  * 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);
             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 */
         if (*pval == NULL) {
             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]);
 
-        j = (j + 1) % width;
-        if (!j)
+        if (++j >= width) {
+            j = 0;
             BIO_printf(out, "\n");
+        }
     }
 
     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);
         return NULL;
     }
-    mask = type & 0xff;
+    mask = type & BIO_TYPE_MASK;
     do {
         if (bio->method != NULL) {
             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
  * 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))
         return -1;
+    if (newval > BIO_TYPE_MASK)
+        return -1;
     return newval;
 }
 

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

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

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

@@ -107,7 +107,7 @@
     || M_METHOD == M_METHOD_WSARECVMSG
 #  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.
      */
 #   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
  * 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
  * this file except in compliance with the License.  You can obtain a copy

+ 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];
     chacha_buf buf;

+ 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
  * 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)
         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;
     if (!EVP_CIPHER_CTX_copy(out->cctx, in->cctx))
         return 0;
@@ -111,6 +111,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
               const EVP_CIPHER *cipher, ENGINE *impl)
 {
     static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 };
+    int block_len;
 
     /* All zeros means restart */
     if (!key && !cipher && !impl && keylen == 0) {
@@ -119,7 +120,10 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
             return 0;
         if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
             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;
         return 1;
     }
@@ -170,7 +174,7 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
         return 0;
     if (dlen == 0)
         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;
     /* Copy into partial block if we need to */
     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)
         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;
     if (poutlen != NULL)
         *poutlen = (size_t)bl;

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

@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-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
@@ -76,6 +76,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     "error validating protection"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_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),
     "failed building own chain"},
     {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"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNCLEAN_CTX), "unclean ctx"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CERTPROFILE),
+     "unexpected certprofile"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_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_SENDER), "unexpected sender"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID),
     "unknown algorithm id"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"},
@@ -156,6 +161,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     "unsupported algorithm"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_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),
     "unsupported protection alg dhbasedmac"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_VALUE_TOO_LARGE), "value too large"},

+ 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 Siemens AG 2015-2019
  *
@@ -64,6 +64,7 @@ struct ossl_cmp_ctx_st {
      * certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf
      */
     int unprotectedErrors;
+    int noCacheExtraCerts;
     X509 *srvCert; /* certificate used to identify the server */
     X509 *validatedSrvCert; /* caches any already validated server cert */
     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 *senderNonce; /* last nonce sent */
     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 */
     STACK_OF(OSSL_CMP_ITAV) *geninfo_ITAVs;
     int implicitConfirm; /* set implicitConfirm in IR/KUR/CR messages */
@@ -254,6 +256,8 @@ struct ossl_cmp_itav_st {
         OSSL_CMP_MSGS *origPKIMessage;
         /* NID_id_it_suppLangTags - Supported Language Tags */
         STACK_OF(ASN1_UTF8STRING) *suppLangTagsValue;
+        /* NID_id_it_certProfile - Certificate Profile */
+        STACK_OF(ASN1_UTF8STRING) *certProfile;
         /* NID_id_it_caCerts - CA Certificates */
         STACK_OF(X509) *caCerts;
         /* 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,
                                  const ASN1_OCTET_STRING *nonce);
 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 */
 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,
                                       const OSSL_CMP_CERTRESPONSE *crep);
 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 */
 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);
 
 /* 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 fail_info, const char *txt);
 int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info,

+ 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
  * 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
  * 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);
     unsigned char *tmp;
     int outl, rv = 0;
+
+    if (blocklen == 0)
+        return 0;
+
     if (inlen < 2 * blocklen) {
         /* too small */
         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 olen;
     int dummy;
+
+    if (blocklen == 0)
+        return 0;
+
     /*
      * First decide length of output buffer: need header and round up to
      * 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
  * 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
  * this file except in compliance with the License.  You can obtain a copy
@@ -11,6 +11,7 @@
 #define OPENSSL_SUPPRESS_DEPRECATED
 
 #include "internal/cryptlib.h"
+#include "internal/rcu.h"
 #include <stdio.h>
 #include <ctype.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_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_IMODULE) *initialized_modules = NULL; /* protected by lock */
 
@@ -86,7 +87,7 @@ static int conf_modules_finish_int(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;
 
     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)
 {
-    module_list_lock = CRYPTO_THREAD_lock_new();
+    module_list_lock = ossl_rcu_lock_new(1);
     if (module_list_lock == NULL) {
         ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
         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_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))
         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;
+
     if ((tmod = OPENSSL_zalloc(sizeof(*tmod))) == NULL)
         goto err;
 
@@ -348,18 +356,24 @@ static CONF_MODULE *module_add(DSO *dso, const char *name,
     if (tmod->name == NULL)
         goto err;
 
-    if (!sk_CONF_MODULE_push(supported_modules, tmod))
+    if (!sk_CONF_MODULE_push(new_modules, tmod))
         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;
 
  err:
-    CRYPTO_THREAD_unlock(module_list_lock);
+    ossl_rcu_write_unlock(module_list_lock);
+    sk_CONF_MODULE_free(new_modules);
     if (tmod != NULL) {
         OPENSSL_free(tmod->name);
         OPENSSL_free(tmod);
     }
+    sk_CONF_MODULE_free(new_modules);
     return NULL;
 }
 
@@ -374,6 +388,8 @@ static CONF_MODULE *module_find(const char *name)
     CONF_MODULE *tmod;
     int i, nchar;
     char *p;
+    STACK_OF(CONF_MODULE) *mods;
+
     p = strrchr(name, '.');
 
     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))
         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) {
-            CRYPTO_THREAD_unlock(module_list_lock);
+            ossl_rcu_read_unlock(module_list_lock);
             return tmod;
         }
     }
 
-    CRYPTO_THREAD_unlock(module_list_lock);
+    ossl_rcu_read_unlock(module_list_lock);
     return NULL;
 }
 
@@ -406,6 +422,8 @@ static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
     int ret = 1;
     int init_called = 0;
     CONF_IMODULE *imod = NULL;
+    STACK_OF(CONF_IMODULE) *old_modules;
+    STACK_OF(CONF_IMODULE) *new_modules;
 
     /* Otherwise add initialized module to list */
     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))
         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);
         goto err;
     }
 
     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;
 
  err:
@@ -482,30 +507,46 @@ void CONF_modules_unload(int all)
 {
     int i;
     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 */
         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;
+    }
 
     /* 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 (((md->links > 0) || !md->dso) && !all)
             continue;
         /* 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 */
@@ -521,23 +562,27 @@ static void module_free(CONF_MODULE *md)
 static int conf_modules_finish_int(void)
 {
     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))
         return 0;
 
     /* 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;
 
-    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);
     }
-    sk_CONF_IMODULE_free(initialized_modules);
-    initialized_modules = NULL;
-
-    CRYPTO_THREAD_unlock(module_list_lock);
+    sk_CONF_IMODULE_free(old_modules);
 
     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
  * 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
  * 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 */
     if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key))
         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;
 err:
     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 */
     if (!ossl_dsa_generate_public_key(ctx, dsa, dsa->priv_key, pub_key))
         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;
 err:
     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
  * 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);
     rsize = len + 1;
-    transform = (strstr(filename, "/") == NULL);
+    transform = (strchr(filename, '/') == NULL);
     if (transform) {
         /* We will convert this to "%s.s?" or "lib%s.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
  * 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);
     rsize = len + 1;
-    transform = (strstr(filename, "/") == NULL);
+    transform = (strchr(filename, '/') == NULL);
     if (transform) {
         /* We will convert this to "%s.so" or "lib%s.so" etc */
         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. */
 # 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 + \
                                     EDDSA_448_PRIVATE_BYTES)
 

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

@@ -26,6 +26,19 @@ int ERR_set_mark(void)
     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)
 {
     ERR_STATE *es;

+ 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
  * 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);
+
+    if (blocksize == 0)
+        return 0;
+
     if (blocksize == 1)
         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;
 }
 
+/* This is a one shot operation */
 int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
 {
     int ret = 0;
@@ -526,10 +527,15 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
         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_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);
 
     ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
@@ -553,6 +559,27 @@ legacy:
     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 *out = EVP_MD_CTX_new();
@@ -1032,6 +1059,12 @@ static void *evp_md_from_algorithm(int name_id,
                 fncnt++;
             }
             break;
+        case OSSL_FUNC_DIGEST_SQUEEZE:
+            if (md->dsqueeze == NULL) {
+                md->dsqueeze = OSSL_FUNC_digest_squeeze(fns);
+                fncnt++;
+            }
+            break;
         case OSSL_FUNC_DIGEST_DIGEST:
             if (md->digest == NULL)
                 md->digest = OSSL_FUNC_digest_digest(fns);
@@ -1075,7 +1108,7 @@ static void *evp_md_from_algorithm(int name_id,
             break;
         }
     }
-    if ((fncnt != 0 && fncnt != 5)
+    if ((fncnt != 0 && fncnt != 5 && fncnt != 6)
         || (fncnt == 0 && md->digest == NULL)) {
         /*
          * 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));
 
         /*
-         * 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.
          */
         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;
     int blocksize;
 
-    if (likely(outl != NULL)) {
+    if (ossl_likely(outl != NULL)) {
         *outl = 0;
     } else {
         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 */
-    if (unlikely(!ctx->encrypt)) {
+    if (ossl_unlikely(!ctx->encrypt)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION);
         return 0;
     }
 
-    if (unlikely(ctx->cipher == NULL)) {
+    if (ossl_unlikely(ctx->cipher == NULL)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
         return 0;
     }
 
-    if (unlikely(ctx->cipher->prov == NULL))
+    if (ossl_unlikely(ctx->cipher->prov == NULL))
         goto legacy;
 
     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);
         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),
                                in, inl_);
 
-    if (likely(ret)) {
+    if (ossl_likely(ret)) {
         if (soutl > INT_MAX) {
             ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
             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;
     int blocksize;
 
-    if (likely(outl != NULL)) {
+    if (ossl_likely(outl != NULL)) {
         *outl = 0;
     } else {
         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 */
-    if (unlikely(ctx->encrypt)) {
+    if (ossl_unlikely(ctx->encrypt)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION);
         return 0;
     }
 
-    if (unlikely(ctx->cipher == NULL)) {
+    if (ossl_unlikely(ctx->cipher == NULL)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
         return 0;
     }
-    if (unlikely(ctx->cipher->prov == NULL))
+    if (ossl_unlikely(ctx->cipher->prov == NULL))
         goto legacy;
 
     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);
         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),
                                in, inl_);
 
-    if (likely(ret)) {
+    if (ossl_likely(ret)) {
         if (soutl > INT_MAX) {
             ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
             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
              * as ossl_namemap_name2num treats the name string as a single name
              * 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)
                 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
  * 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);
     niv = EVP_CIPHER_get_iv_length(type);
     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)
         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
  * 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)
 {
     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
      * 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)
 {
     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
      * 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;
     }
 
+err:
     if (ret == -2)
         ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER);
     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)
 {
-    return cipher->block_size;
+    return (cipher == NULL) ? 0 : cipher->block_size;
 }
 
 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,
                const unsigned char *in, unsigned int inl)
 {
+    if (ctx == NULL || ctx->cipher == NULL)
+        return 0;
+
     if (ctx->cipher->prov != NULL) {
         /*
          * 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 blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
 
+        if (blocksize == 0)
+            return 0;
+
         if (ctx->cipher->ccipher != NULL)
             ret =  ctx->cipher->ccipher(ctx->algctx, out, &outl,
                                         inl + (blocksize == 1 ? 0 : blocksize),
@@ -454,7 +469,7 @@ EVP_CIPHER *EVP_CIPHER_CTX_get1_cipher(EVP_CIPHER_CTX *ctx)
 {
     EVP_CIPHER *cipher;
 
-    if (ctx == NULL)
+    if (ctx == NULL || ctx->cipher == NULL)
         return NULL;
     cipher = (EVP_CIPHER *)ctx->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)
 {
-    return cipher->flags;
+    return cipher == NULL ? 0 : cipher->flags;
 }
 
 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)
 {
-    return cipher->iv_len;
+    return (cipher == NULL) ? 0 : cipher->iv_len;
 }
 
 int EVP_CIPHER_CTX_get_iv_length(const EVP_CIPHER_CTX *ctx)
 {
+    if (ctx->cipher == NULL)
+        return 0;
+
     if (ctx->iv_len < 0) {
         int rv, len = EVP_CIPHER_get_iv_length(ctx->cipher);
         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)
 {
-    return cipher->nid;
+    return (cipher == NULL) ? NID_undef : cipher->nid;
 }
 
 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)

+ 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
  * 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 name_id;
+    /* NID for the legacy alg if there is one */
+    int legacy_alg;
     char *type_name;
     const char *description;
     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
  * this file except in compliance with the License.  You can obtain a copy
@@ -30,6 +30,26 @@ static void *keymgmt_new(void)
     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,
                                     const OSSL_ALGORITHM *algodef,
                                     OSSL_PROVIDER *prov)
@@ -218,6 +238,10 @@ static void *keymgmt_from_algorithm(int name_id,
     if (prov != NULL)
         ossl_provider_up_ref(prov);
 
+#ifndef FIPS_MODULE
+    keymgmt->legacy_alg = get_legacy_alg_type_from_keymgmt(keymgmt);
+#endif
+
     return keymgmt;
 }
 
@@ -275,6 +299,11 @@ int evp_keymgmt_get_number(const EVP_KEYMGMT *keymgmt)
     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)
 {
     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
  * 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)                      \
 {                                                                              \
-    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)                        \
 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;
     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 */
 
 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.
          */
         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 (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
  *
  * 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_total_time;      /* Maximum end time of total transfer, or 0 */
     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 */
@@ -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->wbio = wbio;
     rctx->rbio = rbio;
+    rctx->max_hdr_lines = OSSL_HTTP_DEFAULT_MAX_RESP_HDR_LINES;
     if (rctx->buf == NULL) {
         OPENSSL_free(rctx);
         return NULL;
@@ -355,6 +357,16 @@ int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type
     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,
                         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;
     const unsigned char *p;
     char *buf, *key, *value, *line_end = NULL;
+    size_t resp_hdr_lines = 0;
 
     if (rctx == NULL) {
         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;
         }
 
+        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 */
         if (n == rctx->buf_size) {
             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))
             OSSL_TRACE(HTTP, "]\n");
 
+        resp_hdr_lines = 0;
+
         if (rctx->keep_alive != 0 /* do not let server initiate keep_alive */
                 && !found_keep_alive /* otherwise there is no change */) {
             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
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -12,7 +12,9 @@
 #include <openssl/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[] = {
     {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"},
     {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_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_SERVER_CANCELED_CONNECTION),
     "server canceled connection"},
@@ -70,13 +74,16 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = {
     {0, NULL}
 };
 
-#endif
+# endif
 
 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)
         ERR_load_strings_const(HTTP_str_reasons);
-#endif
+# endif
     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
  * 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;
 #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
  * 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
  * 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 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 *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,
+                          OPENSSL_LH_DOALL_FUNC_THUNK wfunc,
                           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;
     OPENSSL_LH_NODE *a, *n;
@@ -186,9 +205,9 @@ static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
         while (a != NULL) {
             n = a->next;
             if (use_arg)
-                func_arg(a->data, arg);
+                wfunc_arg(a->data, arg, func_arg);
             else
-                func(a->data);
+                wfunc(a->data, func);
             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)
 {
-    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)
@@ -286,24 +322,32 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
 {
     OPENSSL_LH_NODE **ret, *n1;
     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;
 
     nn = hash % lh->pmax;
     if (nn < lh->p)
         nn = hash % lh->num_alloc_nodes;
 
-    cf = lh->comp;
     ret = &(lh->b[(int)nn]);
     for (n1 = *ret; n1 != NULL; n1 = n1->next) {
         if (n1->hash != hash) {
             ret = &(n1->next);
             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);
     }
     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
  * 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_COMPFUNC comp;
     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_alloc_nodes;
     unsigned int p;

+ 2 - 1
libs/openssl/crypto/md5/md5_local.h

@@ -15,7 +15,8 @@
 #ifdef MD5_ASM
 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
      defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
-     defined(_M_X64) || defined(__aarch64__)
+     defined(_M_X64) || defined(__aarch64__) || \
+     (defined(__loongarch__) && __loongarch_grlen == 64)
 #  define md5_block_data_order ossl_md5_block_asm_data_order
 # elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
 #  define md5_block_data_order ossl_md5_block_asm_data_order

+ 25 - 3
libs/openssl/crypto/modes/gcm128.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
  * this file except in compliance with the License.  You can obtain a copy
@@ -393,7 +393,7 @@ void gcm_init_vis3(u128 Htable[16], const u64 Xi[2]);
 void gcm_gmult_vis3(u64 Xi[2], const u128 Htable[16]);
 void gcm_ghash_vis3(u64 Xi[2], const u128 Htable[16], const u8 *inp,
                     size_t len);
-# elif defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
+# elif defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__POWERPC__) || defined(_ARCH_PPC))
 #  include "crypto/ppc_arch.h"
 #  define GHASH_ASM_PPC
 void gcm_init_p8(u128 Htable[16], const u64 Xi[2]);
@@ -413,6 +413,17 @@ void gcm_ghash_rv64i_zbc(u64 Xi[2], const u128 Htable[16],
                          const u8 *inp, size_t len);
 void gcm_ghash_rv64i_zbc__zbkb(u64 Xi[2], const u128 Htable[16],
                                const u8 *inp, size_t len);
+/* zvkb/Zvbc (vector crypto with vclmul) based routines. */
+void gcm_init_rv64i_zvkb_zvbc(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_rv64i_zvkb_zvbc(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_rv64i_zvkb_zvbc(u64 Xi[2], const u128 Htable[16],
+                               const u8 *inp, size_t len);
+/* Zvkg (vector crypto with vgmul.vv and vghsh.vv). */
+void gcm_init_rv64i_zvkg(u128 Htable[16], const u64 Xi[2]);
+void gcm_init_rv64i_zvkg_zvkb(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_rv64i_zvkg(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_rv64i_zvkg(u64 Xi[2], const u128 Htable[16],
+                          const u8 *inp, size_t len);
 # endif
 #endif
 
@@ -512,7 +523,18 @@ static void gcm_get_funcs(struct gcm_funcs_st *ctx)
     ctx->gmult = gcm_gmult_4bit;
     ctx->ghash = gcm_ghash_4bit;
 
-    if (RISCV_HAS_ZBC()) {
+    if (RISCV_HAS_ZVKG() && riscv_vlen() >= 128) {
+        if (RISCV_HAS_ZVKB())
+            ctx->ginit = gcm_init_rv64i_zvkg_zvkb;
+        else
+            ctx->ginit = gcm_init_rv64i_zvkg;
+        ctx->gmult = gcm_gmult_rv64i_zvkg;
+        ctx->ghash = gcm_ghash_rv64i_zvkg;
+    } else if (RISCV_HAS_ZVKB() && RISCV_HAS_ZVBC() && riscv_vlen() >= 128) {
+        ctx->ginit = gcm_init_rv64i_zvkb_zvbc;
+        ctx->gmult = gcm_gmult_rv64i_zvkb_zvbc;
+        ctx->ghash = gcm_ghash_rv64i_zvkb_zvbc;
+    } else if (RISCV_HAS_ZBC()) {
         if (RISCV_HAS_ZBKB()) {
             ctx->ginit = gcm_init_rv64i_zbc__zbkb;
             ctx->gmult = gcm_gmult_rv64i_zbc__zbkb;

+ 11 - 6
libs/openssl/crypto/objects/obj_dat.h

@@ -2,7 +2,7 @@
  * WARNING: do not edit!
  * Generated by crypto/objects/obj_dat.pl
  *
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  * in the file LICENSE in the source distribution or at
@@ -10,7 +10,7 @@
  */
 
 /* Serialized OID's */
-static const unsigned char so[8476] = {
+static const unsigned char so[8487] = {
     0x2A,0x86,0x48,0x86,0xF7,0x0D,                 /* [    0] OBJ_rsadsi */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,            /* [    6] OBJ_pkcs */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,       /* [   13] OBJ_md2 */
@@ -1182,9 +1182,10 @@ static const unsigned char so[8476] = {
     0x55,0x1D,0x49,                                /* [ 8466] OBJ_alt_signature_algorithm */
     0x55,0x1D,0x4A,                                /* [ 8469] OBJ_alt_signature_value */
     0x55,0x1D,0x4B,                                /* [ 8472] OBJ_associated_information */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x33,  /* [ 8475] OBJ_id_ct_rpkiSignedPrefixList */
 };
 
-#define NUM_NID 1320
+#define NUM_NID 1321
 static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"UNDEF", "undefined", NID_undef},
     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2506,9 +2507,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"altSignatureAlgorithm", "X509v3 Alternative Signature Algorithm", NID_alt_signature_algorithm, 3, &so[8466]},
     {"altSignatureValue", "X509v3 Alternative Signature Value", NID_alt_signature_value, 3, &so[8469]},
     {"associatedInformation", "X509v3 Associated Information", NID_associated_information, 3, &so[8472]},
+    {"id-ct-rpkiSignedPrefixList", "id-ct-rpkiSignedPrefixList", NID_id_ct_rpkiSignedPrefixList, 11, &so[8475]},
 };
 
-#define NUM_SN 1311
+#define NUM_SN 1312
 static const unsigned int sn_objs[NUM_SN] = {
      364,    /* "AD_DVCS" */
      419,    /* "AES-128-CBC" */
@@ -3167,6 +3169,7 @@ static const unsigned int sn_objs[NUM_SN] = {
     1234,    /* "id-ct-routeOriginAuthz" */
     1236,    /* "id-ct-rpkiGhostbusters" */
     1235,    /* "id-ct-rpkiManifest" */
+    1320,    /* "id-ct-rpkiSignedPrefixList" */
     1247,    /* "id-ct-signedChecklist" */
     1284,    /* "id-ct-signedTAL" */
     1060,    /* "id-ct-xml" */
@@ -3823,7 +3826,7 @@ static const unsigned int sn_objs[NUM_SN] = {
     1289,    /* "zstd" */
 };
 
-#define NUM_LN 1311
+#define NUM_LN 1312
 static const unsigned int ln_objs[NUM_LN] = {
      363,    /* "AD Time Stamping" */
      405,    /* "ANSI X9.62" */
@@ -4514,6 +4517,7 @@ static const unsigned int ln_objs[NUM_LN] = {
     1234,    /* "id-ct-routeOriginAuthz" */
     1236,    /* "id-ct-rpkiGhostbusters" */
     1235,    /* "id-ct-rpkiManifest" */
+    1320,    /* "id-ct-rpkiSignedPrefixList" */
     1247,    /* "id-ct-signedChecklist" */
     1284,    /* "id-ct-signedTAL" */
     1060,    /* "id-ct-xml" */
@@ -5138,7 +5142,7 @@ static const unsigned int ln_objs[NUM_LN] = {
      125,    /* "zlib compression" */
 };
 
-#define NUM_OBJ 1177
+#define NUM_OBJ 1178
 static const unsigned int obj_objs[NUM_OBJ] = {
        0,    /* OBJ_undef                        0 */
      181,    /* OBJ_iso                          1 */
@@ -6242,6 +6246,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
     1247,    /* OBJ_id_ct_signedChecklist        1 2 840 113549 1 9 16 1 48 */
     1250,    /* OBJ_id_ct_ASPA                   1 2 840 113549 1 9 16 1 49 */
     1284,    /* OBJ_id_ct_signedTAL              1 2 840 113549 1 9 16 1 50 */
+    1320,    /* OBJ_id_ct_rpkiSignedPrefixList   1 2 840 113549 1 9 16 1 51 */
      212,    /* OBJ_id_smime_aa_receiptRequest   1 2 840 113549 1 9 16 2 1 */
      213,    /* OBJ_id_smime_aa_securityLabel    1 2 840 113549 1 9 16 2 2 */
      214,    /* OBJ_id_smime_aa_mlExpandHistory  1 2 840 113549 1 9 16 2 3 */

+ 1 - 1
libs/openssl/crypto/objects/obj_xref.h

@@ -2,7 +2,7 @@
  * WARNING: do not edit!
  * Generated by objxref.pl
  *
- * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy

+ 1 - 17
libs/openssl/crypto/param_build.c

@@ -49,7 +49,7 @@ struct ossl_param_bld_st {
 };
 
 static OSSL_PARAM_BLD_DEF *param_push(OSSL_PARAM_BLD *bld, const char *key,
-                                      int size, size_t alloc, int type,
+                                      size_t size, size_t alloc, int type,
                                       int secure)
 {
     OSSL_PARAM_BLD_DEF *pd = OPENSSL_zalloc(sizeof(*pd));
@@ -257,10 +257,6 @@ int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
 
     if (bsize == 0)
         bsize = strlen(buf);
-    if (bsize > INT_MAX) {
-        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
-        return 0;
-    }
     secure = CRYPTO_secure_allocated(buf);
     pd = param_push(bld, key, bsize, bsize + 1, OSSL_PARAM_UTF8_STRING, secure);
     if (pd == NULL)
@@ -276,10 +272,6 @@ int OSSL_PARAM_BLD_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
 
     if (bsize == 0)
         bsize = strlen(buf);
-    if (bsize > INT_MAX) {
-        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
-        return 0;
-    }
     pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_UTF8_PTR, 0);
     if (pd == NULL)
         return 0;
@@ -293,10 +285,6 @@ int OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD *bld, const char *key,
     OSSL_PARAM_BLD_DEF *pd;
     int secure;
 
-    if (bsize > INT_MAX) {
-        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
-        return 0;
-    }
     secure = CRYPTO_secure_allocated(buf);
     pd = param_push(bld, key, bsize, bsize, OSSL_PARAM_OCTET_STRING, secure);
     if (pd == NULL)
@@ -310,10 +298,6 @@ int OSSL_PARAM_BLD_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key,
 {
     OSSL_PARAM_BLD_DEF *pd;
 
-    if (bsize > INT_MAX) {
-        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
-        return 0;
-    }
     pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_OCTET_PTR, 0);
     if (pd == NULL)
         return 0;

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

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

+ 10 - 2
libs/openssl/crypto/pkcs12/p12_decr.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -26,6 +26,7 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor,
     int outlen, i;
     EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
     int max_out_len, mac_len = 0;
+    int block_size;
 
     if (ctx == NULL) {
         ERR_raise(ERR_LIB_PKCS12, ERR_R_EVP_LIB);
@@ -43,7 +44,14 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor,
      * It's appended to encrypted text on encrypting
      * MAC should be processed on decrypting separately from plain text
      */
-    max_out_len = inlen + EVP_CIPHER_CTX_get_block_size(ctx);
+    block_size = EVP_CIPHER_CTX_get_block_size(ctx);
+
+    if (block_size == 0) {
+        ERR_raise(ERR_LIB_PKCS12, ERR_R_PASSED_NULL_PARAMETER);
+        goto err;
+    }
+
+    max_out_len = inlen + block_size;
     if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx))
                 & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) {
         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, 0, &mac_len) < 0) {

+ 1 - 1
libs/openssl/crypto/pkcs7/pk7_attr.c

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

+ 2 - 3
libs/openssl/crypto/pkcs7/pk7_smime.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -290,9 +290,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
             if (!(flags & PKCS7_NOCRL))
                 X509_STORE_CTX_set0_crls(cert_ctx, p7->d.sign->crl);
             i = X509_verify_cert(cert_ctx);
-            if (i <= 0)
-                j = X509_STORE_CTX_get_error(cert_ctx);
             if (i <= 0) {
+                j = X509_STORE_CTX_get_error(cert_ctx);
                 ERR_raise_data(ERR_LIB_PKCS7, PKCS7_R_CERTIFICATE_VERIFY_ERROR,
                                "Verify error: %s",
                                X509_verify_cert_error_string(j));

+ 48 - 7
libs/openssl/crypto/provider_conf.c

@@ -272,6 +272,42 @@ static int provider_conf_activate(OSSL_LIB_CTX *libctx, const char *name,
     return ok;
 }
 
+static int provider_conf_parse_bool_setting(const char *confname,
+                                            const char *confvalue, int *val)
+{
+
+    if (confvalue == NULL) {
+        ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR,
+                               "directive %s set to unrecognized value",
+                               confname);
+        return 0;
+    }
+    if ((strcmp(confvalue, "1") == 0)
+        || (strcmp(confvalue, "yes") == 0)
+        || (strcmp(confvalue, "YES") == 0)
+        || (strcmp(confvalue, "true") == 0)
+        || (strcmp(confvalue, "TRUE") == 0)
+        || (strcmp(confvalue, "on") == 0)
+        || (strcmp(confvalue, "ON") == 0)) {
+            *val = 1;
+    } else if ((strcmp(confvalue, "0") == 0)
+               || (strcmp(confvalue, "no") == 0)
+               || (strcmp(confvalue, "NO") == 0)
+               || (strcmp(confvalue, "false") == 0)
+               || (strcmp(confvalue, "FALSE") == 0)
+               || (strcmp(confvalue, "off") == 0)
+               || (strcmp(confvalue, "OFF") == 0)) {
+            *val = 0;
+    } else {
+        ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR,
+                               "directive %s set to unrecognized value",
+                               confname);
+        return 0;
+    }
+
+    return 1;
+}
+
 static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
                               const char *value, const CONF *cnf)
 {
@@ -279,7 +315,7 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
     STACK_OF(CONF_VALUE) *ecmds;
     int soft = 0;
     const char *path = NULL;
-    long activate = 0;
+    int activate = 0;
     int ok = 0;
     int added = 0;
 
@@ -306,15 +342,20 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
         /* First handle some special pseudo confs */
 
         /* Override provider name to use */
-        if (strcmp(confname, "identity") == 0)
+        if (strcmp(confname, "identity") == 0) {
             name = confvalue;
-        else if (strcmp(confname, "soft_load") == 0)
-            soft = 1;
+        } else if (strcmp(confname, "soft_load") == 0) {
+            if (!provider_conf_parse_bool_setting(confname,
+                                                  confvalue, &soft))
+                return 0;
         /* Load a dynamic PROVIDER */
-        else if (strcmp(confname, "module") == 0)
+        } else if (strcmp(confname, "module") == 0) {
             path = confvalue;
-        else if (strcmp(confname, "activate") == 0)
-            activate = 1;
+        } else if (strcmp(confname, "activate") == 0) {
+            if (!provider_conf_parse_bool_setting(confname,
+                                                  confvalue, &activate))
+                return 0;
+        }
     }
 
     if (activate) {

+ 1 - 1
libs/openssl/crypto/rand/rand_pool.c

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

+ 3 - 3
libs/openssl/crypto/rand/rand_uniform.c

@@ -34,7 +34,7 @@ uint32_t ossl_rand_uniform_uint32(OSSL_LIB_CTX *ctx, uint32_t upper, int *err)
         *err = 0;
         return 0;
     }
-    if (unlikely(upper == 1))
+    if (ossl_unlikely(upper == 1))
         return 0;
 
     /* Get 32 bits of entropy */
@@ -56,7 +56,7 @@ uint32_t ossl_rand_uniform_uint32(OSSL_LIB_CTX *ctx, uint32_t upper, int *err)
     prod = (uint64_t)upper * rand;
     i = prod >> 32;
     f = prod & 0xffffffff;
-    if (likely(f <= 1 + ~upper))    /* 1+~upper == -upper but compilers whine */
+    if (ossl_likely(f <= 1 + ~upper))    /* 1+~upper == -upper but compilers whine */
         return i;
 
     /*
@@ -85,7 +85,7 @@ uint32_t ossl_rand_uniform_uint32(OSSL_LIB_CTX *ctx, uint32_t upper, int *err)
         if (f < f2)
             return i + 1;
         /* For not all 1 bits, there is no carry so return the result */
-        if (likely(f != 0xffffffff))
+        if (ossl_likely(f != 0xffffffff))
             return i;
         /* setup for the next word of randomness */
         f = prod & 0xffffffff;

+ 144 - 14
libs/openssl/crypto/rsa/rsa_backend.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -64,22 +64,56 @@ static int collect_numbers(STACK_OF(BIGNUM) *numbers,
 int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private)
 {
     const OSSL_PARAM *param_n, *param_e,  *param_d = NULL;
-    BIGNUM *n = NULL, *e = NULL, *d = NULL;
+    const OSSL_PARAM *param_p, *param_q = NULL;
+    const OSSL_PARAM *param_derive = NULL;
+    BIGNUM *p = NULL, *q = NULL, *n = NULL, *e = NULL, *d = NULL;
     STACK_OF(BIGNUM) *factors = NULL, *exps = NULL, *coeffs = NULL;
     int is_private = 0;
+    int derive_from_pq = 0;
+    BN_CTX *ctx = NULL;
 
     if (rsa == NULL)
         return 0;
 
     param_n = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N);
     param_e = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E);
-    if (include_private)
-        param_d = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D);
 
-    if ((param_n != NULL && !OSSL_PARAM_get_BN(param_n, &n))
-        || (param_e != NULL && !OSSL_PARAM_get_BN(param_e, &e))
-        || (param_d != NULL && !OSSL_PARAM_get_BN(param_d, &d)))
+    if ((param_n == NULL || !OSSL_PARAM_get_BN(param_n, &n))
+        || (param_e == NULL || !OSSL_PARAM_get_BN(param_e, &e))) {
+        ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER);
         goto err;
+    }
+
+    if (include_private) {
+
+        param_derive = OSSL_PARAM_locate_const(params,
+                                           OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ);
+        if ((param_derive != NULL)
+            && !OSSL_PARAM_get_int(param_derive, &derive_from_pq))
+            goto err;
+
+        param_d = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D);
+        if (param_d != NULL && !OSSL_PARAM_get_BN(param_d, &d)) {
+            ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER);
+            goto err;
+        }
+
+        if (derive_from_pq) {
+            ctx = BN_CTX_new_ex(rsa->libctx);
+            if (ctx == NULL)
+                goto err;
+
+            /* we need at minimum p, q */
+            param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR1);
+            param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR2);
+            if ((param_p == NULL || !OSSL_PARAM_get_BN(param_p, &p))
+                || (param_q == NULL || !OSSL_PARAM_get_BN(param_q, &q))) {
+                ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER);
+                goto err;
+            }
+
+        }
+    }
 
     is_private = (d != NULL);
 
@@ -96,25 +130,121 @@ int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private)
                                 ossl_rsa_mp_coeff_names))
             goto err;
 
-        /* It's ok if this private key just has n, e and d */
+        if (derive_from_pq && sk_BIGNUM_num(exps) == 0
+            && sk_BIGNUM_num(coeffs) == 0) {
+            /*
+             * If we want to use crt to derive our exponents/coefficients, we
+             * need to have at least 2 factors
+             */
+            if (sk_BIGNUM_num(factors) < 2) {
+                ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER);
+                goto err;
+            }
+
+            /*
+             * if we have more than two factors, n and d must also have
+             * been provided
+             */
+            if (sk_BIGNUM_num(factors) > 2
+                && (param_n == NULL || param_d == NULL)) {
+                ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER);
+                goto err;
+            }
+
+            /* build our exponents and coefficients here */
+            if (sk_BIGNUM_num(factors) == 2) {
+                /* for 2 factors we can use the sp800 functions to do this */
+                if (!RSA_set0_factors(rsa, sk_BIGNUM_value(factors, 0),
+                                      sk_BIGNUM_value(factors, 1))) {
+                    ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR);
+                    goto err;
+                }
+                /*
+                 * once consumed by RSA_set0_factors, pop those off the stack
+                 * so we don't free them below
+                 */
+                sk_BIGNUM_pop(factors);
+                sk_BIGNUM_pop(factors);
+
+                /*
+                 * Note: Because we only have 2 factors here, there will be no
+                 * additional pinfo fields to hold additional factors, and
+                 * since we set our key and 2 factors above we can skip
+                 * the call to ossl_rsa_set0_all_params
+                 */
+                if (!ossl_rsa_sp800_56b_derive_params_from_pq(rsa,
+                                                              RSA_bits(rsa),
+                                                              NULL, ctx)) {
+                    ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR);
+                    goto err;
+                }
+            } else {
+#ifndef FIPS_MODULE
+                /*
+                 * in the multiprime case we have to generate exps/coeffs here
+                 * for each additional prime
+                 */
+                if (!ossl_rsa_multiprime_derive(rsa, RSA_bits(rsa),
+                                                sk_BIGNUM_num(factors),
+                                                rsa->e, factors, exps,
+                                                coeffs)) {
+                    ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR);
+                    goto err;
+                }
+
+                /*
+                 * Now we should have all our factors, exponents and
+                 * coefficients
+                 */
+                if (!ossl_rsa_set0_all_params(rsa, factors, exps, coeffs)) {
+                    ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR);
+                    goto err;
+                }
+
+#else
+                /* multiprime case is disallowed in FIPS mode, raise an error */
+                ERR_raise(ERR_LIB_RSA, ERR_R_UNSUPPORTED);
+                goto err;
+#endif
+            }
+
+        } else {
+            /*
+             * It's ok if this private key just has n, e and d
+             * but only if we're not using derive_from_pq
+             */
+            if (sk_BIGNUM_num(factors) != 0
+                && !ossl_rsa_set0_all_params(rsa, factors, exps, coeffs))
+                goto err;
+        }
+        /* sanity check to ensure we used everything in our stacks */
         if (sk_BIGNUM_num(factors) != 0
-            && !ossl_rsa_set0_all_params(rsa, factors, exps, coeffs))
+            || sk_BIGNUM_num(exps) != 0
+            || sk_BIGNUM_num(coeffs) != 0) {
+            ERR_raise_data(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR,
+                           "There are %d, %d, %d elements left on our factors, exps, coeffs stacks\n",
+                           sk_BIGNUM_num(factors), sk_BIGNUM_num(exps),
+                           sk_BIGNUM_num(coeffs));
             goto err;
+        }
     }
 
-
+    BN_clear_free(p);
+    BN_clear_free(q);
     sk_BIGNUM_free(factors);
     sk_BIGNUM_free(exps);
     sk_BIGNUM_free(coeffs);
+    BN_CTX_free(ctx);
     return 1;
 
  err:
     BN_free(n);
     BN_free(e);
     BN_free(d);
-    sk_BIGNUM_pop_free(factors, BN_free);
-    sk_BIGNUM_pop_free(exps, BN_free);
-    sk_BIGNUM_pop_free(coeffs, BN_free);
+    sk_BIGNUM_pop_free(factors, BN_clear_free);
+    sk_BIGNUM_pop_free(exps, BN_clear_free);
+    sk_BIGNUM_pop_free(coeffs, BN_clear_free);
+    BN_CTX_free(ctx);
     return 0;
 }
 
@@ -152,7 +282,7 @@ int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[],
             || !ossl_param_build_set_multi_key_bn(bld, params,
                                                   ossl_rsa_mp_coeff_names,
                                                   coeffs))
-        goto err;
+            goto err;
     }
 
 #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)

+ 255 - 76
libs/openssl/crypto/rsa/rsa_gen.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -71,15 +71,201 @@ int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes,
     return rsa_keygen(rsa->libctx, rsa, bits, primes, e_value, cb, 0);
 }
 
+DEFINE_STACK_OF(BIGNUM)
+
+/*
+ * Given input values, q, p, n, d and e, derive the exponents
+ * and coefficients for each prime in this key, placing the result
+ * on their respective exps and coeffs stacks
+ */
 #ifndef FIPS_MODULE
+int ossl_rsa_multiprime_derive(RSA *rsa, int bits, int primes,
+                               BIGNUM *e_value,
+                               STACK_OF(BIGNUM) *factors,
+                               STACK_OF(BIGNUM) *exps,
+                               STACK_OF(BIGNUM) *coeffs)
+{
+    STACK_OF(BIGNUM) *pplist = NULL, *pdlist = NULL;
+    BIGNUM *factor = NULL, *newpp = NULL, *newpd = NULL;
+    BIGNUM *dval = NULL, *newexp = NULL, *newcoeff = NULL;
+    BIGNUM *p = NULL, *q = NULL;
+    BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
+    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL;
+    BN_CTX *ctx = NULL;
+    BIGNUM *tmp = NULL;
+    int i;
+    int ret = 0;
+
+    ctx = BN_CTX_new_ex(rsa->libctx);
+    if (ctx == NULL)
+        goto err;
+
+    BN_CTX_start(ctx);
+
+    pplist = sk_BIGNUM_new_null();
+    if (pplist == NULL)
+        goto err;
+
+    pdlist = sk_BIGNUM_new_null();
+    if (pdlist == NULL)
+        goto err;
+
+    r0 = BN_CTX_get(ctx);
+    r1 = BN_CTX_get(ctx);
+    r2 = BN_CTX_get(ctx);
+
+    if (r2 == NULL)
+        goto err;
+
+    BN_set_flags(r0, BN_FLG_CONSTTIME);
+    BN_set_flags(r1, BN_FLG_CONSTTIME);
+    BN_set_flags(r2, BN_FLG_CONSTTIME);
+
+    if (BN_copy(r1, rsa->n) == NULL)
+        goto err;
+
+    p = sk_BIGNUM_value(factors, 0);
+    q = sk_BIGNUM_value(factors, 1);
+
+    /* Build list of partial products of primes */
+    for (i = 0; i < sk_BIGNUM_num(factors); i++) {
+        switch (i) {
+        case 0:
+            /* our first prime, p */
+            if (!BN_sub(r2, p, BN_value_one()))
+                goto err;
+            BN_set_flags(r2, BN_FLG_CONSTTIME);
+            if (BN_mod_inverse(r1, r2, rsa->e, ctx) == NULL)
+                goto err;
+            break;
+        case 1:
+            /* second prime q */
+            if (!BN_mul(r1, p, q, ctx))
+                goto err;
+            tmp = BN_dup(r1);
+            if (tmp == NULL)
+                goto err;
+            if (!sk_BIGNUM_insert(pplist, tmp, sk_BIGNUM_num(pplist)))
+                goto err;
+            break;
+        default:
+            factor = sk_BIGNUM_value(factors, i);
+            /* all other primes */
+            if (!BN_mul(r1, r1, factor, ctx))
+                goto err;
+            tmp = BN_dup(r1);
+            if (tmp == NULL)
+                goto err;
+            if (!sk_BIGNUM_insert(pplist, tmp, sk_BIGNUM_num(pplist)))
+                goto err;
+            break;
+        }
+    }
+
+    /* build list of relative d values */
+    /* p -1 */
+    if (!BN_sub(r1, p, BN_value_one()))
+        goto err;
+    if (!BN_sub(r2, q, BN_value_one()))
+        goto err;
+    if (!BN_mul(r0, r1, r2, ctx))
+        goto err;
+    for (i = 2; i < sk_BIGNUM_num(factors); i++) {
+        factor = sk_BIGNUM_value(factors, i);
+        dval = BN_new();
+        if (dval == NULL)
+            goto err;
+        BN_set_flags(dval, BN_FLG_CONSTTIME);
+        if (!BN_sub(dval, factor, BN_value_one()))
+            goto err;
+        if (!BN_mul(r0, r0, dval, ctx))
+            goto err;
+        if (!sk_BIGNUM_insert(pdlist, dval, sk_BIGNUM_num(pdlist)))
+            goto err;
+    }
+
+    /* Calculate dmp1, dmq1 and additional exponents */
+    dmp1 = BN_secure_new();
+    if (dmp1 == NULL)
+        goto err;
+    dmq1 = BN_secure_new();
+    if (dmq1 == NULL)
+        goto err;
+
+    if (!BN_mod(dmp1, rsa->d, r1, ctx))
+        goto err;
+    if (!sk_BIGNUM_insert(exps, dmp1, sk_BIGNUM_num(exps)))
+        goto err;
+    dmp1 = NULL;
+
+    if (!BN_mod(dmq1, rsa->d, r2, ctx))
+        goto err;
+    if (!sk_BIGNUM_insert(exps, dmq1, sk_BIGNUM_num(exps)))
+        goto err;
+    dmq1 = NULL;
+
+    for (i = 2; i < sk_BIGNUM_num(factors); i++) {
+        newpd = sk_BIGNUM_value(pdlist, i - 2);
+        newexp = BN_new();
+        if (newexp == NULL)
+            goto err;
+        if (!BN_mod(newexp, rsa->d, newpd, ctx)) {
+            BN_free(newexp);
+            goto err;
+        }
+        if (!sk_BIGNUM_insert(exps, newexp, sk_BIGNUM_num(exps)))
+            goto err;
+    }
+
+    /* Calculate iqmp and additional coefficients */
+    iqmp = BN_new();
+    if (iqmp == NULL)
+        goto err;
+
+    if (BN_mod_inverse(iqmp, sk_BIGNUM_value(factors, 1),
+                       sk_BIGNUM_value(factors, 0), ctx) == NULL)
+        goto err;
+    if (!sk_BIGNUM_insert(coeffs, iqmp, sk_BIGNUM_num(coeffs)))
+        goto err;
+    iqmp = NULL;
+
+    for (i = 2; i < sk_BIGNUM_num(factors); i++) {
+        newpp = sk_BIGNUM_value(pplist, i - 2);
+        newcoeff = BN_new();
+        if (newcoeff == NULL)
+            goto err;
+        if (BN_mod_inverse(newcoeff, newpp, sk_BIGNUM_value(factors, i),
+                           ctx) == NULL) {
+            BN_free(newcoeff);
+            goto err;
+        }
+        if (!sk_BIGNUM_insert(coeffs, newcoeff, sk_BIGNUM_num(coeffs)))
+            goto err;
+    }
+
+    ret = 1;
+ err:
+    sk_BIGNUM_pop_free(pplist, BN_free);
+    sk_BIGNUM_pop_free(pdlist, BN_free);
+    BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    BN_clear_free(dmp1);
+    BN_clear_free(dmq1);
+    BN_clear_free(iqmp);
+    return ret;
+}
+
 static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes,
                                  BIGNUM *e_value, BN_GENCB *cb)
 {
-    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *prime;
+    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *tmp2, *prime;
     int n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0;
     int i = 0, quo = 0, rmd = 0, adj = 0, retries = 0;
     RSA_PRIME_INFO *pinfo = NULL;
     STACK_OF(RSA_PRIME_INFO) *prime_infos = NULL;
+    STACK_OF(BIGNUM) *factors = NULL;
+    STACK_OF(BIGNUM) *exps = NULL;
+    STACK_OF(BIGNUM) *coeffs = NULL;
     BN_CTX *ctx = NULL;
     BN_ULONG bitst = 0;
     unsigned long error = 0;
@@ -104,6 +290,18 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes,
         return 0;
     }
 
+    factors = sk_BIGNUM_new_null();
+    if (factors == NULL)
+        return 0;
+
+    exps = sk_BIGNUM_new_null();
+    if (exps == NULL)
+        goto err;
+
+    coeffs = sk_BIGNUM_new_null();
+    if (coeffs == NULL)
+        goto err;
+
     ctx = BN_CTX_new_ex(rsa->libctx);
     if (ctx == NULL)
         goto err;
@@ -137,15 +335,6 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes,
     if (!rsa->q && ((rsa->q = BN_secure_new()) == NULL))
         goto err;
     BN_set_flags(rsa->q, BN_FLG_CONSTTIME);
-    if (!rsa->dmp1 && ((rsa->dmp1 = BN_secure_new()) == NULL))
-        goto err;
-    BN_set_flags(rsa->dmp1, BN_FLG_CONSTTIME);
-    if (!rsa->dmq1 && ((rsa->dmq1 = BN_secure_new()) == NULL))
-        goto err;
-    BN_set_flags(rsa->dmq1, BN_FLG_CONSTTIME);
-    if (!rsa->iqmp && ((rsa->iqmp = BN_secure_new()) == NULL))
-        goto err;
-    BN_set_flags(rsa->iqmp, BN_FLG_CONSTTIME);
 
     /* initialize multi-prime components */
     if (primes > RSA_DEFAULT_PRIME_NUM) {
@@ -220,7 +409,7 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes,
             ERR_set_mark();
             BN_set_flags(r2, BN_FLG_CONSTTIME);
             if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
-               /* GCD == 1 since inverse exists */
+                /* GCD == 1 since inverse exists */
                 break;
             }
             error = ERR_peek_last_error();
@@ -250,8 +439,14 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes,
             /* i == 0, do nothing */
             if (!BN_GENCB_call(cb, 3, i))
                 goto err;
+            tmp = BN_dup(prime);
+            if (tmp == NULL)
+                goto err;
+            if (!sk_BIGNUM_insert(factors, tmp, sk_BIGNUM_num(factors)))
+                goto err;
             continue;
         }
+
         /*
          * if |r1|, product of factors so far, is not as long as expected
          * (by checking the first 4 bits are less than 0x9 or greater than
@@ -298,6 +493,10 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes,
                  */
                 i = -1;
                 bitse = 0;
+                sk_BIGNUM_pop_free(factors, BN_clear_free);
+                factors = sk_BIGNUM_new_null();
+                if (factors == NULL)
+                    goto err;
                 continue;
             }
             retries++;
@@ -310,12 +509,20 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes,
             goto err;
         if (!BN_GENCB_call(cb, 3, i))
             goto err;
+        tmp = BN_dup(prime);
+        if (tmp == NULL)
+            goto err;
+        if (!sk_BIGNUM_insert(factors, tmp, sk_BIGNUM_num(factors)))
+            goto err;
     }
 
     if (BN_cmp(rsa->p, rsa->q) < 0) {
         tmp = rsa->p;
         rsa->p = rsa->q;
         rsa->q = tmp;
+        /* mirror this in our factor stack */
+        if (!sk_BIGNUM_insert(factors, sk_BIGNUM_delete(factors, 0), 1))
+            goto err;
     }
 
     /* calculate d */
@@ -339,79 +546,51 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes,
             goto err;
     }
 
-    {
-        BIGNUM *pr0 = BN_new();
 
-        if (pr0 == NULL)
-            goto err;
-
-        BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
-        if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
-            BN_free(pr0);
-            goto err;               /* d */
-        }
-        /* We MUST free pr0 before any further use of r0 */
-        BN_free(pr0);
-    }
-
-    {
-        BIGNUM *d = BN_new();
-
-        if (d == NULL)
-            goto err;
-
-        BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
-
-        /* calculate d mod (p-1) and d mod (q - 1) */
-        if (!BN_mod(rsa->dmp1, d, r1, ctx)
-            || !BN_mod(rsa->dmq1, d, r2, ctx)) {
-            BN_free(d);
-            goto err;
-        }
-
-        /* calculate CRT exponents */
-        for (i = 2; i < primes; i++) {
-            pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2);
-            /* pinfo->d == r_i - 1 */
-            if (!BN_mod(pinfo->d, d, pinfo->d, ctx)) {
-                BN_free(d);
-                goto err;
-            }
-        }
-
-        /* We MUST free d before any further use of rsa->d */
-        BN_free(d);
+    BN_set_flags(r0, BN_FLG_CONSTTIME);
+    if (BN_mod_inverse(rsa->d, rsa->e, r0, ctx) == NULL) {
+        goto err;               /* d */
     }
 
-    {
-        BIGNUM *p = BN_new();
+    /* derive any missing exponents and coefficients */
+    if (!ossl_rsa_multiprime_derive(rsa, bits, primes, e_value,
+                                    factors, exps, coeffs))
+        goto err;
 
-        if (p == NULL)
+    /*
+     * first 2 factors/exps are already tracked in p/q/dmq1/dmp1
+     * and the first coeff is in iqmp, so pop those off the stack
+     * Note, the first 2 factors/exponents are already tracked by p and q
+     * assign dmp1/dmq1 and iqmp
+     * the remaining pinfo values are separately allocated, so copy and delete 
+     * those
+     */
+    BN_clear_free(sk_BIGNUM_delete(factors, 0));
+    BN_clear_free(sk_BIGNUM_delete(factors, 0));
+    rsa->dmp1 = sk_BIGNUM_delete(exps, 0);
+    rsa->dmq1 = sk_BIGNUM_delete(exps, 0);
+    rsa->iqmp = sk_BIGNUM_delete(coeffs, 0);
+    for (i = 2; i < primes; i++) {
+        pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2);
+        tmp = sk_BIGNUM_delete(factors, 0);
+        BN_copy(pinfo->r, tmp);
+        BN_clear_free(tmp);
+        tmp = sk_BIGNUM_delete(exps, 0);
+        tmp2 = BN_copy(pinfo->d, tmp);
+        BN_clear_free(tmp);
+        if (tmp2 == NULL)
             goto err;
-        BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
-
-        /* calculate inverse of q mod p */
-        if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) {
-            BN_free(p);
+        tmp = sk_BIGNUM_delete(coeffs, 0);
+        tmp2 = BN_copy(pinfo->t, tmp);
+        BN_clear_free(tmp);
+        if (tmp2 == NULL)
             goto err;
-        }
-
-        /* calculate CRT coefficient for other primes */
-        for (i = 2; i < primes; i++) {
-            pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2);
-            BN_with_flags(p, pinfo->r, BN_FLG_CONSTTIME);
-            if (!BN_mod_inverse(pinfo->t, pinfo->pp, p, ctx)) {
-                BN_free(p);
-                goto err;
-            }
-        }
-
-        /* We MUST free p before any further use of rsa->p */
-        BN_free(p);
     }
-
     ok = 1;
  err:
+    sk_BIGNUM_free(factors);
+    sk_BIGNUM_free(exps);
+    sk_BIGNUM_free(coeffs);
     if (ok == -1) {
         ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB);
         ok = 0;

+ 29 - 7
libs/openssl/crypto/rsa/rsa_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
  * this file except in compliance with the License.  You can obtain a copy
@@ -744,9 +744,13 @@ int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2)
 
 DEFINE_STACK_OF(BIGNUM)
 
-int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
-                             const STACK_OF(BIGNUM) *exps,
-                             const STACK_OF(BIGNUM) *coeffs)
+/*
+ * Note: This function deletes values from the parameter
+ * stack values as they are consumed and set in the RSA key.
+ */
+int ossl_rsa_set0_all_params(RSA *r, STACK_OF(BIGNUM) *primes,
+                             STACK_OF(BIGNUM) *exps,
+                             STACK_OF(BIGNUM) *coeffs)
 {
 #ifndef FIPS_MODULE
     STACK_OF(RSA_PRIME_INFO) *prime_infos, *old_infos = NULL;
@@ -757,6 +761,8 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
         return 0;
 
     pnum = sk_BIGNUM_num(primes);
+
+    /* we need at least 2 primes */
     if (pnum < 2)
         return 0;
 
@@ -764,6 +770,17 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
                           sk_BIGNUM_value(primes, 1)))
         return 0;
 
+    /*
+     * if we managed to set everything above, remove those elements from the
+     * stack
+     * Note, we do this after the above all to ensure that we have taken
+     * ownership of all the elements in the RSA key to avoid memory leaks
+     * we also use delete 0 here as we are grabbing items from the end of the
+     * stack rather than the start, otherwise we could use pop
+     */
+    sk_BIGNUM_delete(primes, 0);
+    sk_BIGNUM_delete(primes, 0);
+
     if (pnum == sk_BIGNUM_num(exps)
         && pnum == sk_BIGNUM_num(coeffs) + 1) {
 
@@ -771,6 +788,11 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
                                  sk_BIGNUM_value(exps, 1),
                                  sk_BIGNUM_value(coeffs, 0)))
         return 0;
+
+        /* as above, once we consume the above params, delete them from the list */
+        sk_BIGNUM_delete(exps, 0);
+        sk_BIGNUM_delete(exps, 0);
+        sk_BIGNUM_delete(coeffs, 0);
     }
 
 #ifndef FIPS_MODULE
@@ -786,9 +808,9 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
             return 0;
 
         for (i = 2; i < pnum; i++) {
-            BIGNUM *prime = sk_BIGNUM_value(primes, i);
-            BIGNUM *exp = sk_BIGNUM_value(exps, i);
-            BIGNUM *coeff = sk_BIGNUM_value(coeffs, i - 1);
+            BIGNUM *prime = sk_BIGNUM_pop(primes);
+            BIGNUM *exp = sk_BIGNUM_pop(exps);
+            BIGNUM *coeff = sk_BIGNUM_pop(coeffs);
             RSA_PRIME_INFO *pinfo = NULL;
 
             if (!ossl_assert(prime != NULL && exp != NULL && coeff != NULL))

+ 5 - 1
libs/openssl/crypto/rsa/rsa_local.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -150,6 +150,10 @@ struct rsa_meth_st {
 /* Macros to test if a pkey or ctx is for a PSS key */
 #define pkey_is_pss(pkey) (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS)
 #define pkey_ctx_is_pss(ctx) (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS)
+int ossl_rsa_multiprime_derive(RSA *rsa, int bits, int primes,
+                                 BIGNUM *e_value,
+                                 STACK_OF(BIGNUM) *factors, STACK_OF(BIGNUM) *exps,
+                                 STACK_OF(BIGNUM) *coeffs);
 
 RSA_PSS_PARAMS *ossl_rsa_pss_params_create(const EVP_MD *sigmd,
                                            const EVP_MD *mgf1md, int saltlen);

+ 38 - 33
libs/openssl/crypto/rsa/rsa_sp800_56b_gen.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2024 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2018-2019, Oracle and/or its affiliates.  All rights reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -30,7 +30,6 @@
  *     test Object used for CAVS testing only.that contains..
  *       p1, p2 The returned auxiliary primes for p.
  *              If NULL they are not returned.
- *       Xpout An optionally returned random number used during generation of p.
  *       Xp An optional passed in value (that is random number used during
  *          generation of p).
  *       Xp1, Xp2 Optionally passed in randomly generated numbers from which
@@ -38,7 +37,6 @@
  *                are generated internally.
  *       q1, q2 The returned auxiliary primes for q.
  *              If NULL they are not returned.
- *       Xqout An optionally returned random number used during generation of q.
  *       Xq An optional passed in value (that is random number used during
  *          generation of q).
  *       Xq1, Xq2 Optionally passed in randomly generated numbers from which
@@ -50,7 +48,7 @@
  *     cb An optional BIGNUM callback.
  * Returns: 1 if successful, or  0 otherwise.
  * Notes:
- *     p1, p2, q1, q2, Xpout, Xqout are returned if they are not NULL.
+ *     p1, p2, q1, q2 are returned if they are not NULL.
  *     Xp, Xp1, Xp2, Xq, Xq1, Xq2 are optionally passed in.
  *     (Required for CAVS testing).
  */
@@ -65,7 +63,6 @@ int ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test,
     BIGNUM *p1 = NULL, *p2 = NULL;
     BIGNUM *q1 = NULL, *q2 = NULL;
     /* Intermediate BIGNUMS that can be input for testing */
-    BIGNUM *Xpout = NULL, *Xqout = NULL;
     BIGNUM *Xp = NULL, *Xp1 = NULL, *Xp2 = NULL;
     BIGNUM *Xq = NULL, *Xq1 = NULL, *Xq2 = NULL;
 
@@ -105,8 +102,8 @@ int ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test,
 
     BN_CTX_start(ctx);
     tmp = BN_CTX_get(ctx);
-    Xpo = (Xpout != NULL) ? Xpout : BN_CTX_get(ctx);
-    Xqo = (Xqout != NULL) ? Xqout : BN_CTX_get(ctx);
+    Xpo = BN_CTX_get(ctx);
+    Xqo = BN_CTX_get(ctx);
     if (tmp == NULL || Xpo == NULL || Xqo == NULL)
         goto err;
     BN_set_flags(Xpo, BN_FLG_CONSTTIME);
@@ -150,9 +147,9 @@ int ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test,
     ret = 1;
 err:
     /* Zeroize any internally generated values that are not returned */
-    if (Xpo != Xpout)
+    if (Xpo != NULL)
         BN_clear(Xpo);
-    if (Xqo != Xqout)
+    if (Xqo != NULL)
         BN_clear(Xqo);
     BN_clear(tmp);
 
@@ -228,13 +225,16 @@ static int rsa_validate_rng_strength(EVP_RAND_CTX *rng, int nbits)
  * Returns: -1 = error,
  *           0 = d is too small,
  *           1 = success.
+ *
+ * SP800-56b key generation always passes a non NULL value for e.
+ * For other purposes, if e is NULL then it is assumed that e, n and d are
+ * already set in the RSA key and do not need to be recalculated.
  */
 int ossl_rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits,
                                              const BIGNUM *e, BN_CTX *ctx)
 {
     int ret = -1;
     BIGNUM *p1, *q1, *lcm, *p1q1, *gcd;
-
     BN_CTX_start(ctx);
     p1 = BN_CTX_get(ctx);
     q1 = BN_CTX_get(ctx);
@@ -254,32 +254,37 @@ int ossl_rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits,
     if (ossl_rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, p1q1) != 1)
         goto err;
 
-    /* copy e */
-    BN_free(rsa->e);
-    rsa->e = BN_dup(e);
-    if (rsa->e == NULL)
-        goto err;
+    /*
+     * if e is provided as a parameter, don't recompute e, d or n
+     */
+    if (e != NULL) {
+        /* copy e */
+        BN_free(rsa->e);
+        rsa->e = BN_dup(e);
+        if (rsa->e == NULL)
+            goto err;
 
-    BN_clear_free(rsa->d);
-    /* (Step 3) d = (e^-1) mod (LCM(p-1, q-1)) */
-    rsa->d = BN_secure_new();
-    if (rsa->d == NULL)
-        goto err;
-    BN_set_flags(rsa->d, BN_FLG_CONSTTIME);
-    if (BN_mod_inverse(rsa->d, e, lcm, ctx) == NULL)
-        goto err;
+        BN_clear_free(rsa->d);
+        /* (Step 3) d = (e^-1) mod (LCM(p-1, q-1)) */
+        rsa->d = BN_secure_new();
+        if (rsa->d == NULL)
+            goto err;
+        BN_set_flags(rsa->d, BN_FLG_CONSTTIME);
+        if (BN_mod_inverse(rsa->d, e, lcm, ctx) == NULL)
+            goto err;
 
-    /* (Step 3) return an error if d is too small */
-    if (BN_num_bits(rsa->d) <= (nbits >> 1)) {
-        ret = 0;
-        goto err;
-    }
+        /* (Step 3) return an error if d is too small */
+        if (BN_num_bits(rsa->d) <= (nbits >> 1)) {
+            ret = 0;
+            goto err;
+        }
 
-    /* (Step 4) n = pq */
-    if (rsa->n == NULL)
-        rsa->n = BN_new();
-    if (rsa->n == NULL || !BN_mul(rsa->n, rsa->p, rsa->q, ctx))
-        goto err;
+        /* (Step 4) n = pq */
+        if (rsa->n == NULL)
+            rsa->n = BN_new();
+        if (rsa->n == NULL || !BN_mul(rsa->n, rsa->p, rsa->q, ctx))
+            goto err;
+    }
 
     /* (Step 5a) dP = d mod (p-1) */
     if (rsa->dmp1 == NULL)

+ 13 - 6
libs/openssl/crypto/sha/keccak1600.c

@@ -13,7 +13,7 @@
 
 size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len,
                    size_t r);
-void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r);
+void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r, int next);
 
 #if !defined(KECCAK1600_ASM) || !defined(SELFTEST)
 
@@ -1090,10 +1090,16 @@ size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len,
 }
 
 /*
- * sha3_squeeze is called once at the end to generate |out| hash value
- * of |len| bytes.
+ * SHA3_squeeze may be called after SHA3_absorb to generate |out| hash value of
+ * |len| bytes.
+ * If multiple SHA3_squeeze calls are required the output length |len| must be a
+ * multiple of the blocksize, with |next| being 0 on the first call and 1 on
+ * subsequent calls. It is the callers responsibility to buffer the results.
+ * When only a single call to SHA3_squeeze is required, |len| can be any size
+ * and |next| must be 0.
  */
-void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r)
+void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r,
+                  int next)
 {
     uint64_t *A_flat = (uint64_t *)A;
     size_t i, w = r / 8;
@@ -1101,6 +1107,9 @@ void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r)
     assert(r < (25 * sizeof(A[0][0])) && (r % 8) == 0);
 
     while (len != 0) {
+        if (next)
+            KeccakF1600(A);
+        next = 1;
         for (i = 0; i < w && len != 0; i++) {
             uint64_t Ai = BitDeinterleave(A_flat[i]);
 
@@ -1123,8 +1132,6 @@ void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r)
             out += 8;
             len -= 8;
         }
-        if (len)
-            KeccakF1600(A);
     }
 }
 #endif

+ 10 - 2
libs/openssl/crypto/sha/sha256.c

@@ -116,12 +116,16 @@ int SHA224_Final(unsigned char *md, SHA256_CTX *c)
 #define HASH_BLOCK_DATA_ORDER   sha256_block_data_order
 #ifndef SHA256_ASM
 static
-#endif
+#else
+# ifdef INCLUDE_C_SHA256
+void sha256_block_data_order_c(SHA256_CTX *ctx, const void *in, size_t num);
+# endif /* INCLUDE_C_SHA256 */
+#endif /* SHA256_ASM */
 void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
 
 #include "crypto/md32_common.h"
 
-#ifndef SHA256_ASM
+#if !defined(SHA256_ASM) || defined(INCLUDE_C_SHA256)
 static const SHA_LONG K256[64] = {
     0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
     0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
@@ -279,8 +283,12 @@ static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
         T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];    \
         ROUND_00_15(i,a,b,c,d,e,f,g,h);         } while (0)
 
+#ifdef INCLUDE_C_SHA256
+void sha256_block_data_order_c(SHA256_CTX *ctx, const void *in, size_t num)
+#else
 static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
                                     size_t num)
+#endif
 {
     unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1;
     SHA_LONG X[16];

+ 96 - 4
libs/openssl/crypto/sha/sha3.c

@@ -10,12 +10,13 @@
 #include <string.h>
 #include "internal/sha3.h"
 
-void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r);
+void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r, int next);
 
 void ossl_sha3_reset(KECCAK1600_CTX *ctx)
 {
     memset(ctx->A, 0, sizeof(ctx->A));
     ctx->bufsz = 0;
+    ctx->xof_state = XOF_STATE_INIT;
 }
 
 int ossl_sha3_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen)
@@ -51,6 +52,10 @@ int ossl_sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len)
     if (len == 0)
         return 1;
 
+    if (ctx->xof_state == XOF_STATE_SQUEEZE
+        || ctx->xof_state == XOF_STATE_FINAL)
+        return 0;
+
     if ((num = ctx->bufsz) != 0) {      /* process intermediate buffer? */
         rem = bsz - num;
 
@@ -84,13 +89,21 @@ int ossl_sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len)
     return 1;
 }
 
-int ossl_sha3_final(unsigned char *md, KECCAK1600_CTX *ctx)
+/*
+ * ossl_sha3_final()is a single shot method
+ * (Use ossl_sha3_squeeze for multiple calls).
+ * outlen is the variable size output.
+ */
+int ossl_sha3_final(KECCAK1600_CTX *ctx, unsigned char *out, size_t outlen)
 {
     size_t bsz = ctx->block_size;
     size_t num = ctx->bufsz;
 
-    if (ctx->md_size == 0)
+    if (outlen == 0)
         return 1;
+    if (ctx->xof_state == XOF_STATE_SQUEEZE
+        || ctx->xof_state == XOF_STATE_FINAL)
+        return 0;
 
     /*
      * Pad the data with 10*1. Note that |num| can be |bsz - 1|
@@ -103,7 +116,86 @@ int ossl_sha3_final(unsigned char *md, KECCAK1600_CTX *ctx)
 
     (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
 
-    SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
+    ctx->xof_state = XOF_STATE_FINAL;
+    SHA3_squeeze(ctx->A, out, outlen, bsz, 0);
+    return 1;
+}
+
+/*
+ * This method can be called multiple times.
+ * Rather than heavily modifying assembler for SHA3_squeeze(),
+ * we instead just use the limitations of the existing function.
+ * i.e. Only request multiples of the ctx->block_size when calling
+ * SHA3_squeeze(). For output length requests smaller than the
+ * ctx->block_size just request a single ctx->block_size bytes and
+ * buffer the results. The next request will use the buffer first
+ * to grab output bytes.
+ */
+int ossl_sha3_squeeze(KECCAK1600_CTX *ctx, unsigned char *out, size_t outlen)
+{
+    size_t bsz = ctx->block_size;
+    size_t num = ctx->bufsz;
+    size_t len;
+    int next = 1;
+
+    if (outlen == 0)
+        return 1;
+
+    if (ctx->xof_state == XOF_STATE_FINAL)
+        return 0;
+
+    /*
+     * On the first squeeze call, finish the absorb process,
+     * by adding the trailing padding and then doing
+     * a final absorb.
+     */
+    if (ctx->xof_state != XOF_STATE_SQUEEZE) {
+        /*
+         * Pad the data with 10*1. Note that |num| can be |bsz - 1|
+         * in which case both byte operations below are performed on
+         * same byte...
+         */
+        memset(ctx->buf + num, 0, bsz - num);
+        ctx->buf[num] = ctx->pad;
+        ctx->buf[bsz - 1] |= 0x80;
+        (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
+        ctx->xof_state = XOF_STATE_SQUEEZE;
+        num = ctx->bufsz = 0;
+        next = 0;
+    }
+
+    /*
+     * Step 1. Consume any bytes left over from a previous squeeze
+     * (See Step 4 below).
+     */
+    if (num != 0) {
+        if (outlen > ctx->bufsz)
+            len = ctx->bufsz;
+        else
+            len = outlen;
+        memcpy(out, ctx->buf + bsz - ctx->bufsz, len);
+        out += len;
+        outlen -= len;
+        ctx->bufsz -= len;
+    }
+    if (outlen == 0)
+        return 1;
+
+    /* Step 2. Copy full sized squeezed blocks to the output buffer directly */
+    if (outlen >= bsz) {
+        len = bsz * (outlen / bsz);
+        SHA3_squeeze(ctx->A, out, len, bsz, next);
+        next = 1;
+        out += len;
+        outlen -= len;
+    }
+    if (outlen > 0) {
+        /* Step 3. Squeeze one more block into a buffer */
+        SHA3_squeeze(ctx->A, ctx->buf, bsz, bsz, next);
+        memcpy(out, ctx->buf, outlen);
+        /* Step 4. Remember the leftover part of the squeezed block */
+        ctx->bufsz = bsz - outlen;
+    }
 
     return 1;
 }

+ 9 - 1
libs/openssl/crypto/sha/sha512.c

@@ -149,6 +149,10 @@ int SHA512_Init(SHA512_CTX *c)
 
 #ifndef SHA512_ASM
 static
+#else
+# ifdef INCLUDE_C_SHA512
+void sha512_block_data_order_c(SHA512_CTX *ctx, const void *in, size_t num);
+# endif
 #endif
 void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
 
@@ -338,7 +342,7 @@ void SHA512_Transform(SHA512_CTX *c, const unsigned char *data)
     sha512_block_data_order(c, data, 1);
 }
 
-#ifndef SHA512_ASM
+#if !defined(SHA512_ASM) || defined(INCLUDE_C_SHA512)
 static const SHA_LONG64 K512[80] = {
     U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
     U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
@@ -737,8 +741,12 @@ static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
         T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f];    \
         ROUND_00_15(i+j,a,b,c,d,e,f,g,h);               } while (0)
 
+#ifdef INCLUDE_C_SHA512
+void sha512_block_data_order_c(SHA512_CTX *ctx, const void *in, size_t num)
+#else
 static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
                                     size_t num)
+#endif
 {
     const SHA_LONG64 *W = in;
     SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1;

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

@@ -31,7 +31,8 @@ void OSSL_sleep(uint64_t millis)
     unsigned int s = (unsigned int)(millis / 1000);
     unsigned int us = (unsigned int)((millis % 1000) * 1000);
 
-    sleep(s);
+    if (s > 0)
+        sleep(s);
     usleep(us);
 # endif
 }

+ 4 - 17
libs/openssl/crypto/sm2/sm2_crypt.c

@@ -46,25 +46,12 @@ IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext)
 
 static size_t ec_field_size(const EC_GROUP *group)
 {
-    /* Is there some simpler way to do this? */
-    BIGNUM *p = BN_new();
-    BIGNUM *a = BN_new();
-    BIGNUM *b = BN_new();
-    size_t field_size = 0;
+    const BIGNUM *p = EC_GROUP_get0_field(group);
 
-    if (p == NULL || a == NULL || b == NULL)
-       goto done;
-
-    if (!EC_GROUP_get_curve(group, p, a, b, NULL))
-        goto done;
-    field_size = (BN_num_bits(p) + 7) / 8;
-
- done:
-    BN_free(p);
-    BN_free(a);
-    BN_free(b);
+    if (p == NULL)
+        return 0;
 
-    return field_size;
+    return BN_num_bytes(p);
 }
 
 static int is_all_zeros(const unsigned char *msg, size_t msglen)

+ 6 - 1
libs/openssl/crypto/sm3/sm3_local.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright 2017 Ribose Inc. All Rights Reserved.
  * Ported from Ribose contributions from Botan.
  *
@@ -39,6 +39,11 @@
 #  define HWSM3_CAPABLE (OPENSSL_armcap_P & ARMV8_SM3)
 void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num);
 # endif
+# if defined(__riscv) && __riscv_xlen == 64
+#  include "crypto/riscv_arch.h"
+#  define HWSM3_CAPABLE 1
+void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num);
+# endif
 #endif
 
 #if defined(HWSM3_CAPABLE)

+ 2 - 2
libs/openssl/crypto/stack/stack.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -397,7 +397,7 @@ int OPENSSL_sk_find_all(OPENSSL_STACK *st, const void *data, int *pnum)
 int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
 {
     if (st == NULL)
-        return -1;
+        return 0;
     return OPENSSL_sk_insert(st, data, st->num);
 }
 

+ 358 - 3
libs/openssl/crypto/threads_win.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -13,6 +13,7 @@
 // WINSCP #  define USE_RWLOCK
 # endif
 #endif
+#include <assert.h>
 
 /*
  * VC++ 2008 or earlier x86 compilers do not have an inline implementation
@@ -27,6 +28,11 @@
 #endif
 
 #include <openssl/crypto.h>
+#include <crypto/cryptlib.h>
+#include "internal/common.h"
+#include "internal/thread_arch.h"
+#include "internal/rcu.h"
+#include "rcu_internal.h"
 
 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && defined(OPENSSL_SYS_WINDOWS)
 
@@ -37,20 +43,369 @@ typedef struct {
 } CRYPTO_win_rwlock;
 # endif
 
+static CRYPTO_THREAD_LOCAL rcu_thr_key;
+
+# define READER_SHIFT 0
+# define ID_SHIFT 32 
+# define READER_SIZE 32 
+# define ID_SIZE 32 
+
+# define READER_MASK     (((LONG64)1 << READER_SIZE)-1)
+# define ID_MASK         (((LONG64)1 << ID_SIZE)-1)
+# define READER_COUNT(x) (((LONG64)(x) >> READER_SHIFT) & READER_MASK)
+# define ID_VAL(x)       (((LONG64)(x) >> ID_SHIFT) & ID_MASK)
+# define VAL_READER      ((LONG64)1 << READER_SHIFT)
+# define VAL_ID(x)       ((LONG64)x << ID_SHIFT)
+
+/*
+ * This defines a quescent point (qp)
+ * This is the barrier beyond which a writer
+ * must wait before freeing data that was
+ * atomically updated
+ */
+struct rcu_qp {
+    volatile LONG64 users;
+};
+
+struct thread_qp {
+    struct rcu_qp *qp;
+    unsigned int depth;
+    CRYPTO_RCU_LOCK *lock;
+};
+
+#define MAX_QPS 10
+/*
+ * This is the per thread tracking data
+ * that is assigned to each thread participating
+ * in an rcu qp
+ *
+ * qp points to the qp that it last acquired
+ *
+ */
+struct rcu_thr_data {
+    struct thread_qp thread_qps[MAX_QPS];
+};
+
+/*
+ * This is the internal version of a CRYPTO_RCU_LOCK
+ * it is cast from CRYPTO_RCU_LOCK
+ */
+struct rcu_lock_st {
+    struct rcu_cb_item *cb_items;
+    uint32_t id_ctr;
+    struct rcu_qp *qp_group;
+    size_t group_count;
+    uint32_t next_to_retire;
+    volatile long int reader_idx;
+    uint32_t current_alloc_idx;
+    uint32_t writers_alloced;
+    CRYPTO_MUTEX *write_lock;
+    CRYPTO_MUTEX *alloc_lock;
+    CRYPTO_CONDVAR *alloc_signal;
+    CRYPTO_MUTEX *prior_lock;
+    CRYPTO_CONDVAR *prior_signal;
+};
+
+/*
+ * Called on thread exit to free the pthread key
+ * associated with this thread, if any
+ */
+static void free_rcu_thr_data(void *ptr)
+{
+    struct rcu_thr_data *data =
+                        (struct rcu_thr_data *)CRYPTO_THREAD_get_local(&rcu_thr_key);
+
+    OPENSSL_free(data);
+    CRYPTO_THREAD_set_local(&rcu_thr_key, NULL);
+}
+
+
+static void ossl_rcu_init(void)
+{
+    CRYPTO_THREAD_init_local(&rcu_thr_key, NULL);
+    ossl_init_thread_start(NULL, NULL, free_rcu_thr_data);
+}
+
+static struct rcu_qp *allocate_new_qp_group(struct rcu_lock_st *lock,
+                                            int count)
+{
+    struct rcu_qp *new =
+        OPENSSL_zalloc(sizeof(*new) * count);
+
+    lock->group_count = count;
+    return new;
+}
+
+static CRYPTO_ONCE rcu_init_once = CRYPTO_ONCE_STATIC_INIT;
+
+CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers)
+{
+    struct rcu_lock_st *new;
+
+    if (!CRYPTO_THREAD_run_once(&rcu_init_once, ossl_rcu_init))
+        return NULL;
+
+    if (num_writers < 1)
+        num_writers = 1;
+
+    new = OPENSSL_zalloc(sizeof(*new));
+
+    if (new == NULL)
+        return NULL;
+
+    new->write_lock = ossl_crypto_mutex_new();
+    new->alloc_signal = ossl_crypto_condvar_new();
+    new->prior_signal = ossl_crypto_condvar_new();
+    new->alloc_lock = ossl_crypto_mutex_new();
+    new->prior_lock = ossl_crypto_mutex_new();
+    new->qp_group = allocate_new_qp_group(new, num_writers + 1);
+    if (new->qp_group == NULL
+        || new->alloc_signal == NULL
+        || new->prior_signal == NULL
+        || new->write_lock == NULL
+        || new->alloc_lock == NULL
+        || new->prior_lock == NULL) {
+        OPENSSL_free(new->qp_group);
+        ossl_crypto_condvar_free(&new->alloc_signal);
+        ossl_crypto_condvar_free(&new->prior_signal);
+        ossl_crypto_mutex_free(&new->alloc_lock);
+        ossl_crypto_mutex_free(&new->prior_lock);
+        ossl_crypto_mutex_free(&new->write_lock);
+        OPENSSL_free(new);
+        new = NULL;
+    }
+    return new;
+
+}
+
+void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock)
+{
+    OPENSSL_free(lock->qp_group);
+    ossl_crypto_condvar_free(&lock->alloc_signal);
+    ossl_crypto_condvar_free(&lock->prior_signal);
+    ossl_crypto_mutex_free(&lock->alloc_lock);
+    ossl_crypto_mutex_free(&lock->prior_lock);
+    ossl_crypto_mutex_free(&lock->write_lock);
+    OPENSSL_free(lock);
+}
+
+static ossl_inline struct rcu_qp *get_hold_current_qp(CRYPTO_RCU_LOCK *lock)
+{
+    uint32_t qp_idx;
+
+    /* get the current qp index */
+    for (;;) {
+        qp_idx = InterlockedOr(&lock->reader_idx, 0);
+        InterlockedAdd64(&lock->qp_group[qp_idx].users, VAL_READER);
+        if (qp_idx == InterlockedOr(&lock->reader_idx, 0))
+            break;
+        InterlockedAdd64(&lock->qp_group[qp_idx].users, -VAL_READER);
+    }
+
+    return &lock->qp_group[qp_idx];
+}
+
+void ossl_rcu_read_lock(CRYPTO_RCU_LOCK *lock)
+{
+    struct rcu_thr_data *data;
+    int i;
+    int available_qp = -1;
+
+    /*
+     * we're going to access current_qp here so ask the
+     * processor to fetch it
+     */
+    data = CRYPTO_THREAD_get_local(&rcu_thr_key);
+
+    if (data == NULL) {
+        data = OPENSSL_zalloc(sizeof(*data));
+        OPENSSL_assert(data != NULL);
+        CRYPTO_THREAD_set_local(&rcu_thr_key, data);
+    }
+
+    for (i = 0; i < MAX_QPS; i++) {
+        if (data->thread_qps[i].qp == NULL && available_qp == -1)
+            available_qp = i;
+        /* If we have a hold on this lock already, we're good */
+        if (data->thread_qps[i].lock == lock)
+            return;
+    }
+
+    /*
+     * if we get here, then we don't have a hold on this lock yet
+     */
+    assert(available_qp != -1);
+
+    data->thread_qps[available_qp].qp = get_hold_current_qp(lock);
+    data->thread_qps[available_qp].depth = 1;
+    data->thread_qps[available_qp].lock = lock;
+}
+
+void ossl_rcu_write_lock(CRYPTO_RCU_LOCK *lock)
+{
+    ossl_crypto_mutex_lock(lock->write_lock);
+}
+
+void ossl_rcu_write_unlock(CRYPTO_RCU_LOCK *lock)
+{
+    ossl_crypto_mutex_unlock(lock->write_lock);
+}
+
+void ossl_rcu_read_unlock(CRYPTO_RCU_LOCK *lock)
+{
+    struct rcu_thr_data *data = CRYPTO_THREAD_get_local(&rcu_thr_key);
+    int i;
+    LONG64 ret;
+
+    assert(data != NULL);
+
+    for (i = 0; i < MAX_QPS; i++) {
+        if (data->thread_qps[i].lock == lock) {
+            data->thread_qps[i].depth--;
+            if (data->thread_qps[i].depth == 0) {
+                ret = InterlockedAdd64(&data->thread_qps[i].qp->users, -VAL_READER);
+                OPENSSL_assert(ret >= 0);
+                data->thread_qps[i].qp = NULL;
+                data->thread_qps[i].lock = NULL;
+            }
+            return;
+        }
+    }
+}
+
+static struct rcu_qp *update_qp(CRYPTO_RCU_LOCK *lock)
+{
+    uint64_t new_id;
+    uint32_t current_idx;
+    uint32_t tmp;
+
+    ossl_crypto_mutex_lock(lock->alloc_lock);
+    /*
+     * we need at least one qp to be available with one
+     * left over, so that readers can start working on
+     * one that isn't yet being waited on
+     */
+    while (lock->group_count - lock->writers_alloced < 2)
+        ossl_crypto_condvar_wait(lock->alloc_signal, lock->alloc_lock);
+
+    current_idx = lock->current_alloc_idx;
+    /* Allocate the qp */
+    lock->writers_alloced++;
+
+    /* increment the allocation index */
+    lock->current_alloc_idx =
+        (lock->current_alloc_idx + 1) % lock->group_count;
+
+    /* get and insert a new id */
+    new_id = lock->id_ctr;
+    lock->id_ctr++;
+
+    new_id = VAL_ID(new_id);
+    InterlockedAnd64(&lock->qp_group[current_idx].users, ID_MASK);
+    InterlockedAdd64(&lock->qp_group[current_idx].users, new_id);
+
+    /* update the reader index to be the prior qp */
+    tmp = lock->current_alloc_idx;
+    InterlockedExchange(&lock->reader_idx, tmp);
+
+    /* wake up any waiters */
+    ossl_crypto_condvar_broadcast(lock->alloc_signal);
+    ossl_crypto_mutex_unlock(lock->alloc_lock);
+    return &lock->qp_group[current_idx];
+}
+
+static void retire_qp(CRYPTO_RCU_LOCK *lock,
+                      struct rcu_qp *qp)
+{
+    ossl_crypto_mutex_lock(lock->alloc_lock);
+    lock->writers_alloced--;
+    ossl_crypto_condvar_broadcast(lock->alloc_signal);
+    ossl_crypto_mutex_unlock(lock->alloc_lock);
+}
+
+
+void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock)
+{
+    struct rcu_qp *qp;
+    uint64_t count;
+    struct rcu_cb_item *cb_items, *tmpcb;
+
+    /* before we do anything else, lets grab the cb list */
+    cb_items = InterlockedExchangePointer((void * volatile *)&lock->cb_items, NULL);
+
+    qp = update_qp(lock);
+
+    /* wait for the reader count to reach zero */
+    do {
+        count = InterlockedOr64(&qp->users, 0);
+    } while (READER_COUNT(count) != 0);
+
+    /* retire in order */
+    ossl_crypto_mutex_lock(lock->prior_lock);
+    while (lock->next_to_retire != ID_VAL(count))
+        ossl_crypto_condvar_wait(lock->prior_signal, lock->prior_lock);
+
+    lock->next_to_retire++;
+    ossl_crypto_condvar_broadcast(lock->prior_signal);
+    ossl_crypto_mutex_unlock(lock->prior_lock);
+
+    retire_qp(lock, qp);
+
+    /* handle any callbacks that we have */
+    while (cb_items != NULL) {
+        tmpcb = cb_items;
+        cb_items = cb_items->next;
+        tmpcb->fn(tmpcb->data);
+        OPENSSL_free(tmpcb);
+    }
+
+    /* and we're done */
+    return;
+
+}
+
+int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data)
+{
+    struct rcu_cb_item *new;
+    struct rcu_cb_item *prev;
+
+    new = OPENSSL_zalloc(sizeof(struct rcu_cb_item));
+    if (new == NULL)
+        return 0;
+    prev = new;
+    new->data = data;
+    new->fn = cb;
+
+    InterlockedExchangePointer((void * volatile *)&lock->cb_items, prev);
+    new->next = prev;
+    return 1;
+}
+
+void *ossl_rcu_uptr_deref(void **p)
+{
+    return (void *)*p;
+}
+
+void ossl_rcu_assign_uptr(void **p, void **v)
+{
+    InterlockedExchangePointer((void * volatile *)p, (void *)*v);
+}
+
+
 CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
 {
     CRYPTO_RWLOCK *lock;
 # ifdef USE_RWLOCK
     CRYPTO_win_rwlock *rwlock;
 
-    if ((lock = CRYPTO_zalloc(sizeof(CRYPTO_win_rwlock), NULL, 0)) == NULL)
+    if ((lock = OPENSSL_zalloc(sizeof(CRYPTO_win_rwlock))) == NULL)
         /* Don't set error, to avoid recursion blowup. */
         return NULL;
     rwlock = lock;
     InitializeSRWLock(&rwlock->lock);
 # else
 
-    if ((lock = CRYPTO_zalloc(sizeof(CRITICAL_SECTION), NULL, 0)) == NULL)
+    if ((lock = OPENSSL_zalloc(sizeof(CRITICAL_SECTION))) == NULL)
         /* Don't set error, to avoid recursion blowup. */
         return NULL;
 

+ 1 - 1
libs/openssl/crypto/x509/t_req.c

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

+ 1 - 1
libs/openssl/crypto/x509/t_x509.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
  * this file except in compliance with the License.  You can obtain a copy

+ 4 - 0
libs/openssl/crypto/x509/v3_addr.c

@@ -300,6 +300,8 @@ static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
             return -1;
         prefixlen_a = length * 8;
         break;
+    default:
+        return -1;
     }
 
     switch (b->type) {
@@ -313,6 +315,8 @@ static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
             return -1;
         prefixlen_b = length * 8;
         break;
+    default:
+        return -1;
     }
 
     if ((r = memcmp(addr_a, addr_b, length)) != 0)

+ 0 - 3
libs/openssl/crypto/x509/v3_ist.c

@@ -103,9 +103,6 @@ static int i2r_issuer_sign_tool(X509V3_EXT_METHOD *method,
         return 0;
     }
     if (ist->signTool != NULL) {
-        if (new_line == 1) {
-            BIO_write(out, "\n", 1);
-        }
         BIO_printf(out, "%*ssignTool    : ", indent, "");
         BIO_write(out, ist->signTool->data, ist->signTool->length);
         new_line = 1;

+ 31 - 1
libs/openssl/crypto/x509/x509_lu.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -583,6 +583,36 @@ STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *xs)
     return xs->objs;
 }
 
+static X509_OBJECT *x509_object_dup(const X509_OBJECT *obj)
+{
+    X509_OBJECT *ret = X509_OBJECT_new();
+    if (ret == NULL)
+        return NULL;
+
+    ret->type = obj->type;
+    ret->data = obj->data;
+    X509_OBJECT_up_ref_count(ret);
+    return ret;
+}
+
+STACK_OF(X509_OBJECT) *X509_STORE_get1_objects(X509_STORE *store)
+{
+    STACK_OF(X509_OBJECT) *objs;
+
+    if (store == NULL) {
+        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+
+    if (!x509_store_read_lock(store))
+        return NULL;
+
+    objs = sk_X509_OBJECT_deep_copy(store->objs, x509_object_dup,
+                                    X509_OBJECT_free);
+    X509_STORE_unlock(store);
+    return objs;
+}
+
 STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store)
 {
     STACK_OF(X509) *sk;

+ 80 - 6
libs/openssl/include/crypto/aes_platform.h

@@ -60,7 +60,7 @@ void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
 # endif /* AES_XTS_ASM */
 
 # if defined(OPENSSL_CPUID_OBJ)
-#  if (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
+#  if (defined(__powerpc__) || defined(__POWERPC__) || defined(_ARCH_PPC))
 #   include "crypto/ppc_arch.h"
 #   ifdef VPAES_ASM
 #    define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC)
@@ -107,17 +107,21 @@ void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len);
 #    define HWAES_cbc_encrypt aes_v8_cbc_encrypt
 #    define HWAES_ecb_encrypt aes_v8_ecb_encrypt
 #    if __ARM_MAX_ARCH__>=8 && (defined(__aarch64__) || defined(_M_ARM64))
+#     define ARMv8_HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
 #     define HWAES_xts_encrypt aes_v8_xts_encrypt
 #     define HWAES_xts_decrypt aes_v8_xts_decrypt
 #    endif
 #    define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
+#    define HWAES_ctr32_encrypt_blocks_unroll12_eor3 aes_v8_ctr32_encrypt_blocks_unroll12_eor3
 #    define AES_PMULL_CAPABLE ((OPENSSL_armcap_P & ARMV8_PMULL) && (OPENSSL_armcap_P & ARMV8_AES))
+#    define AES_UNROLL12_EOR3_CAPABLE (OPENSSL_armcap_P & ARMV8_UNROLL12_EOR3)
 #    define AES_GCM_ENC_BYTES 512
 #    define AES_GCM_DEC_BYTES 512
 #    if __ARM_MAX_ARCH__>=8 && (defined(__aarch64__) || defined(_M_ARM64))
 #     define AES_gcm_encrypt armv8_aes_gcm_encrypt
 #     define AES_gcm_decrypt armv8_aes_gcm_decrypt
-#     define AES_GCM_ASM(gctx) ((gctx)->ctr==aes_v8_ctr32_encrypt_blocks && \
+#     define AES_GCM_ASM(gctx) (((gctx)->ctr==aes_v8_ctr32_encrypt_blocks_unroll12_eor3 || \
+                                 (gctx)->ctr==aes_v8_ctr32_encrypt_blocks) && \
                                 (gctx)->gcm.funcs.ghash==gcm_ghash_v8)
 /* The [unroll8_eor3_]aes_gcm_(enc|dec)_(128|192|256)_kernel() functions
  * take input length in BITS and return number of BYTES processed */
@@ -435,14 +439,79 @@ void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
 /* RISC-V 64 support */
 #  include "riscv_arch.h"
 
+/* Zkne and Zknd extensions (scalar crypto AES). */
 int rv64i_zkne_set_encrypt_key(const unsigned char *userKey, const int bits,
-                          AES_KEY *key);
+                               AES_KEY *key);
 int rv64i_zknd_set_decrypt_key(const unsigned char *userKey, const int bits,
-                          AES_KEY *key);
+                               AES_KEY *key);
 void rv64i_zkne_encrypt(const unsigned char *in, unsigned char *out,
-                   const AES_KEY *key);
+                        const AES_KEY *key);
 void rv64i_zknd_decrypt(const unsigned char *in, unsigned char *out,
-                   const AES_KEY *key);
+                        const AES_KEY *key);
+/* Zvkned extension (vector crypto AES). */
+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);
+void rv64i_zvkned_encrypt(const unsigned char *in, unsigned char *out,
+                          const AES_KEY *key);
+void rv64i_zvkned_decrypt(const unsigned char *in, unsigned char *out,
+                          const AES_KEY *key);
+
+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);
+
+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);
+
+void rv64i_zvkned_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                              size_t length, const AES_KEY *key,
+                              const int enc);
+
+void rv64i_zvkned_ecb_decrypt(const unsigned char *in, unsigned char *out,
+                              size_t length, const AES_KEY *key,
+                              const int enc);
+
+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]);
+
+size_t rv64i_zvkb_zvkg_zvkned_aes_gcm_encrypt(const unsigned char *in,
+                                              unsigned char *out, size_t len,
+                                              const void *key,
+                                              unsigned char ivec[16], u64 *Xi);
+
+size_t rv64i_zvkb_zvkg_zvkned_aes_gcm_decrypt(const unsigned char *in,
+                                              unsigned char *out, size_t len,
+                                              const void *key,
+                                              unsigned char ivec[16], u64 *Xi);
+
+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]);
+
+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]);
+
+void gcm_ghash_rv64i_zvkg(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                          size_t len);
+
+#define AES_GCM_ENC_BYTES 64
+#define AES_GCM_DEC_BYTES 64
+#define AES_gcm_encrypt rv64i_zvkb_zvkg_zvkned_aes_gcm_encrypt
+#define AES_gcm_decrypt rv64i_zvkb_zvkg_zvkned_aes_gcm_decrypt
+#define AES_GCM_ASM(ctx)                                                       \
+    (ctx->ctr == rv64i_zvkb_zvkned_ctr32_encrypt_blocks &&                     \
+     ctx->gcm.funcs.ghash == gcm_ghash_rv64i_zvkg)
+
 # elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32
 /* RISC-V 32 support */
 #  include "riscv_arch.h"
@@ -480,6 +549,11 @@ void HWAES_ecb_encrypt(const unsigned char *in, unsigned char *out,
 void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
                                 size_t len, const void *key,
                                 const unsigned char ivec[16]);
+#  if defined(AES_UNROLL12_EOR3_CAPABLE)
+void HWAES_ctr32_encrypt_blocks_unroll12_eor3(const unsigned char *in, unsigned char *out,
+                                              size_t len, const void *key,
+                                              const unsigned char ivec[16]);
+#  endif
 void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out,
                        size_t len, const AES_KEY *key1,
                        const AES_KEY *key2, const unsigned char iv[16]);

+ 6 - 0
libs/openssl/include/crypto/chacha.h

@@ -27,6 +27,12 @@
 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
+/* The fallback implementation for `ChaCha20_ctr32`. */
+void ChaCha20_ctr32_c(unsigned char *out, const unsigned char *inp, size_t len,
+                      const unsigned int key[8], const unsigned int counter[4]);
+#endif
+
 /*
  * You can notice that there is no key setup procedure. Because it's
  * as trivial as collecting bytes into 32-bit elements, it's reckoned

+ 5 - 0
libs/openssl/include/crypto/dsa.h

@@ -15,6 +15,11 @@
 # include <openssl/dsa.h>
 # include "internal/ffc.h"
 
+/*
+ * DSA Paramgen types
+ * Note, adding to this list requires adjustments to various checks
+ * in dsa_gen range validation checks
+ */
 #define DSA_PARAMGEN_TYPE_FIPS_186_4   0   /* Use FIPS186-4 standard */
 #define DSA_PARAMGEN_TYPE_FIPS_186_2   1   /* Use legacy FIPS186-2 standard */
 #define DSA_PARAMGEN_TYPE_FIPS_DEFAULT 2

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -282,6 +282,7 @@ struct evp_md_st {
     OSSL_FUNC_digest_init_fn *dinit;
     OSSL_FUNC_digest_update_fn *dupdate;
     OSSL_FUNC_digest_final_fn *dfinal;
+    OSSL_FUNC_digest_squeeze_fn *dsqueeze;
     OSSL_FUNC_digest_digest_fn *digest;
     OSSL_FUNC_digest_freectx_fn *freectx;
     OSSL_FUNC_digest_dupctx_fn *dupctx;
@@ -950,6 +951,7 @@ int evp_kdf_get_number(const EVP_KDF *kdf);
 int evp_kem_get_number(const EVP_KEM *wrap);
 int evp_keyexch_get_number(const EVP_KEYEXCH *keyexch);
 int evp_keymgmt_get_number(const EVP_KEYMGMT *keymgmt);
+int evp_keymgmt_get_legacy_alg(const EVP_KEYMGMT *keymgmt);
 int evp_mac_get_number(const EVP_MAC *mac);
 int evp_md_get_number(const EVP_MD *md);
 int evp_rand_get_number(const EVP_RAND *rand);

+ 4 - 1
libs/openssl/include/crypto/httperr.h

@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -19,7 +19,10 @@
 extern "C" {
 # endif
 
+# ifndef OPENSSL_NO_HTTP
+
 int ossl_err_load_HTTP_strings(void);
+# endif
 
 # ifdef  __cplusplus
 }

+ 10 - 0
libs/openssl/include/crypto/riscv_arch.def

@@ -32,6 +32,16 @@ RISCV_DEFINE_CAP(ZKSED, 0, 10)
 RISCV_DEFINE_CAP(ZKSH, 0, 11)
 RISCV_DEFINE_CAP(ZKR, 0, 12)
 RISCV_DEFINE_CAP(ZKT, 0, 13)
+RISCV_DEFINE_CAP(V, 0, 14)
+RISCV_DEFINE_CAP(ZVBB, 0, 15)
+RISCV_DEFINE_CAP(ZVBC, 0, 16)
+RISCV_DEFINE_CAP(ZVKB, 0, 17)
+RISCV_DEFINE_CAP(ZVKG, 0, 18)
+RISCV_DEFINE_CAP(ZVKNED, 0, 19)
+RISCV_DEFINE_CAP(ZVKNHA, 0, 20)
+RISCV_DEFINE_CAP(ZVKNHB, 0, 21)
+RISCV_DEFINE_CAP(ZVKSED, 0, 22)
+RISCV_DEFINE_CAP(ZVKSH, 0, 23)
 
 /*
  * In the future ...

+ 15 - 0
libs/openssl/include/crypto/riscv_arch.h

@@ -60,5 +60,20 @@ static const size_t kRISCVNumCaps =
 #define RISCV_HAS_ZBB_AND_ZBC() (RISCV_HAS_ZBB() && RISCV_HAS_ZBC())
 #define RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE() (RISCV_HAS_ZBKB() && RISCV_HAS_ZKND() && RISCV_HAS_ZKNE())
 #define RISCV_HAS_ZKND_AND_ZKNE() (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE())
+/*
+ * The ZVBB is the superset of ZVKB extension. We use macro here to replace the
+ * `RISCV_HAS_ZVKB()` with `RISCV_HAS_ZVBB() || RISCV_HAS_ZVKB()`.
+ */
+#define RISCV_HAS_ZVKB() (RISCV_HAS_ZVBB() || RISCV_HAS_ZVKB())
+#define RISCV_HAS_ZVKB_AND_ZVKNHA() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKNHA())
+#define RISCV_HAS_ZVKB_AND_ZVKNHB() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKNHB())
+#define RISCV_HAS_ZVKB_AND_ZVKSED() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKSED())
+#define RISCV_HAS_ZVKB_AND_ZVKSH() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKSH())
+
+/*
+ * Get the size of a vector register in bits (VLEN).
+ * If RISCV_HAS_V() is false, then this returns 0.
+ */
+size_t riscv_vlen(void);
 
 #endif

+ 4 - 4
libs/openssl/include/crypto/rsa.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -54,9 +54,9 @@ RSA *ossl_rsa_new_with_ctx(OSSL_LIB_CTX *libctx);
 OSSL_LIB_CTX *ossl_rsa_get0_libctx(RSA *r);
 void ossl_rsa_set0_libctx(RSA *r, OSSL_LIB_CTX *libctx);
 
-int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
-                             const STACK_OF(BIGNUM) *exps,
-                             const STACK_OF(BIGNUM) *coeffs);
+int ossl_rsa_set0_all_params(RSA *r, STACK_OF(BIGNUM) *primes,
+                             STACK_OF(BIGNUM) *exps,
+                             STACK_OF(BIGNUM) *coeffs);
 int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes,
                              STACK_OF(BIGNUM_const) *exps,
                              STACK_OF(BIGNUM_const) *coeffs);

+ 13 - 1
libs/openssl/include/crypto/sm4_platform.h

@@ -38,7 +38,19 @@ static inline int vpsm4_ex_capable(void)
 #   define HWSM4_cbc_encrypt sm4_v8_cbc_encrypt
 #   define HWSM4_ecb_encrypt sm4_v8_ecb_encrypt
 #   define HWSM4_ctr32_encrypt_blocks sm4_v8_ctr32_encrypt_blocks
-#  endif
+#  elif defined(__riscv) && __riscv_xlen == 64
+/* RV64 support */
+#   include "riscv_arch.h"
+/* Zvksed extension (vector crypto SM4). */
+int rv64i_zvksed_sm4_set_encrypt_key(const unsigned char *userKey,
+                                     SM4_KEY *key);
+int rv64i_zvksed_sm4_set_decrypt_key(const unsigned char *userKey,
+                                     SM4_KEY *key);
+void rv64i_zvksed_sm4_encrypt(const unsigned char *in, unsigned char *out,
+                              const SM4_KEY *key);
+void rv64i_zvksed_sm4_decrypt(const unsigned char *in, unsigned char *out,
+                              const SM4_KEY *key);
+#  endif /* RV64 */
 # endif /* OPENSSL_CPUID_OBJ */
 
 # if defined(HWSM4_CAPABLE)

+ 20 - 6
libs/openssl/include/internal/common.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -19,11 +19,11 @@
 # include "internal/nelem.h"
 
 # if defined(__GNUC__) || defined(__clang__)
-#  define likely(x)     __builtin_expect(!!(x), 1)
-#  define unlikely(x)   __builtin_expect(!!(x), 0)
+#  define ossl_likely(x)     __builtin_expect(!!(x), 1)
+#  define ossl_unlikely(x)   __builtin_expect(!!(x), 0)
 # else
-#  define likely(x)     x
-#  define unlikely(x)   x
+#  define ossl_likely(x)     x
+#  define ossl_unlikely(x)   x
 # endif
 
 # if defined(__GNUC__) || defined(__clang__)
@@ -38,7 +38,7 @@
 # endif
 
 # ifdef NDEBUG
-#  define ossl_assert(x) ((x) != 0)
+#  define ossl_assert(x) ossl_likely((x) != 0)
 # else
 __owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr,
                                               const char *file, int line)
@@ -198,6 +198,20 @@ static ossl_inline int ossl_ends_with_dirsep(const char *path)
     return *path == '/';
 }
 
+static ossl_inline char ossl_determine_dirsep(const char *path)
+{
+    if (ossl_ends_with_dirsep(path))
+        return '\0';
+
+# if defined(_WIN32)
+    return '\\';
+# elif defined(__VMS)
+    return ':';
+# else
+    return '/';
+# endif
+}
+
 static ossl_inline int ossl_is_absolute_path(const char *path)
 {
 # if defined __VMS

+ 226 - 0
libs/openssl/include/internal/json_enc.h

@@ -0,0 +1,226 @@
+/*
+ * 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
+ */
+
+#ifndef OSSL_JSON_ENC_H
+# define OSSL_JSON_ENC_H
+
+# include <openssl/bio.h>
+
+/*
+ * JSON Encoder
+ * ============
+ *
+ * This JSON encoder is used for qlog. It supports ordinary JSON (RFC 7159),
+ * JSON-SEQ (RFC 7464) and I-JSON (RFC 7493). It supports only basic ASCII.
+ */
+
+struct json_write_buf {
+    BIO     *bio;
+    char    *buf;
+    size_t  alloc, cur;
+};
+
+typedef struct ossl_json_enc_st {
+    uint32_t                flags;
+    /* error: 1 if an error has occurred. */
+    /* state: current state. */
+    /* stack stores a bitmap. 0=object, 1=array. */
+    /* stack cur   size: stack_end_byte bytes, stack_end_bit bits. */
+    /* stack alloc size: stack_bytes bytes. */
+    unsigned char           error, stack_end_bit, state, *stack, defer_indent;
+    unsigned char           stack_small[16];
+    struct json_write_buf   wbuf;
+    size_t                  stack_end_byte, stack_bytes;
+} OSSL_JSON_ENC;
+
+/*
+ * ossl_json_init
+ * --------------
+ *
+ * Initialises a JSON encoder.
+ *
+ * If the flag OSSL_JSON_FLAG_SEQ is passed, the output is in JSON-SEQ. The
+ * caller should use the encoder as though it is encoding members of a JSON
+ * array (but without calling ossl_json_array_begin() or ossl_json_array_end()).
+ * Each top-level JSON item (e.g. JSON object) encoded will be separated
+ * correctly as per the JSON-SEQ format.
+ *
+ * If the flag OSSL_JSON_FLAG_SEQ is not passed, the output is in JSON format.
+ * Generally the caller should encode only a single output item (e.g. a JSON
+ * object).
+ *
+ * By default, JSON output is maximally compact. If OSSL_JSON_FLAG_PRETTY is
+ * set, JSON/JSON-SEQ output is spaced for optimal human readability.
+ *
+ * If OSSL_JSON_FLAG_IJSON is set, integers outside the range `[-2**53 + 1,
+ * 2**53 - 1]` are automatically converted to decimal strings before
+ * serialization.
+ */
+#define OSSL_JSON_FLAG_NONE    0
+#define OSSL_JSON_FLAG_SEQ     (1U << 0)
+#define OSSL_JSON_FLAG_PRETTY  (1U << 1)
+#define OSSL_JSON_FLAG_IJSON   (1U << 2)
+
+int ossl_json_init(OSSL_JSON_ENC *json, BIO *bio, uint32_t flags);
+
+/*
+ * ossl_json_cleanup
+ * -----------------
+ *
+ * Destroys a JSON encoder.
+ */
+void ossl_json_cleanup(OSSL_JSON_ENC *json);
+
+/*
+ * ossl_json_reset
+ * ---------------
+ *
+ * Resets a JSON encoder, as though it has just been initialised, allowing it
+ * to be used again for new output syntactically unrelated to any previous
+ * output. This is similar to calling ossl_json_cleanup followed by
+ * ossl_json_init but may allow internal buffers to be reused.
+ *
+ * If the JSON encoder has entered an error state, this function MAY allow
+ * recovery from this error state, in which case it will return 1. If this
+ * function returns 0, the JSON encoder is unrecoverable and
+ * ossl_json_cleanup() must be called.
+ *
+ * Automatically calls ossl_json_flush().
+ */
+int ossl_json_reset(OSSL_JSON_ENC *json);
+
+/*
+ * ossl_json_flush
+ * ---------------
+ *
+ * Flushes the JSON encoder, ensuring that any residual bytes in internal
+ * buffers are written to the provided sink BIO. Flushing may also happen
+ * autonomously as buffers are filled, but the caller must use this function
+ * to guarantee all data has been flushed.
+ */
+int ossl_json_flush(OSSL_JSON_ENC *json);
+
+/*
+ * ossl_json_flush_cleanup
+ * -----------------------
+ *
+ * Tries to flush as in a call to ossl_json_flush, and then calls
+ * ossl_json_cleanup regardless of the result. The result of the flush call is
+ * returned.
+ */
+int ossl_json_flush_cleanup(OSSL_JSON_ENC *json);
+
+/*
+ * ossl_json_set0_sink
+ * -------------------
+ *
+ * Changes the sink used by the JSON encoder.
+ */
+int ossl_json_set0_sink(OSSL_JSON_ENC *json, BIO *bio);
+
+/*
+ * ossl_json_in_error
+ * ------------------
+ *
+ * To enhance the ergonomics of the JSON API, the JSON object uses an implicit
+ * error tracking model. When a JSON API call fails (for example due to caller
+ * error, such as trying to close an array which was not opened), the JSON
+ * object enters an error state and all further calls are silently ignored.
+ *
+ * The caller can detect this condition after it is finished making builder
+ * calls to the JSON object by calling this function. This function returns 1
+ * if an error occurred. At this point the caller's only recourse is to call
+ * ossl_json_reset() or ossl_json_cleanup().
+ *
+ * Note that partial (i.e., invalid) output may still have been sent to the BIO
+ * in this case. Since the amount of output which can potentially be produced
+ * by a JSON object is unbounded, it is impractical to buffer it all before
+ * flushing. It is expected that errors will ordinarily be either caller errors
+ * (programming errors) or BIO errors.
+ */
+int ossl_json_in_error(OSSL_JSON_ENC *json);
+
+/*
+ * JSON Builder Calls
+ * ==================
+ *
+ * These functions are used to build JSON output. The functions which have
+ * begin and end function pairs must be called in correctly nested sequence.
+ * When writing an object, ossl_json_key() must be called exactly once before
+ * each call to write a JSON item.
+ *
+ * The JSON library takes responsibility for enforcing correct usage patterns.
+ * If a call is made that does not correspond to the JSON syntax, the JSON
+ * object enters the error state and all subsequent calls are ignored.
+ *
+ * In JSON-SEQ mode, the caller should act as though the library implicitly
+ * places all calls between an ossl_json_array_begin() and
+ * ossl_json_array_end() pair; for example, the normal usage pattern would be
+ * to call ossl_json_object_begin() followed by ossl_json_object_end(), in
+ * repeated sequence.
+ *
+ * The library does not enforce non-generation of duplicate keys. Avoiding this
+ * is the caller's responsibility. It is also the caller's responsibility to
+ * pass valid UTF-8 strings. All other forms of invalid output will cause an
+ * error. Note that due to the immediate nature of the API, partial output may
+ * have already been generated in such a case.
+ */
+
+/* Begin a new JSON object. */
+void ossl_json_object_begin(OSSL_JSON_ENC *json);
+
+/* End a JSON object. Must be matched with a call to ossl_json_object_begin(). */
+void ossl_json_object_end(OSSL_JSON_ENC *json);
+
+/* Begin a new JSON array. */
+void ossl_json_array_begin(OSSL_JSON_ENC *json);
+
+/* End a JSON array. Must be matched with a call to ossl_json_array_end(). */
+void ossl_json_array_end(OSSL_JSON_ENC *json);
+
+/*
+ * Encode a JSON key within an object. Pass a zero-terminated string, which can
+ * be freed immediately following the call to this function.
+ */
+void ossl_json_key(OSSL_JSON_ENC *json, const char *key);
+
+/* Encode a JSON 'null' value. */
+void ossl_json_null(OSSL_JSON_ENC *json);
+
+/* Encode a JSON boolean value. */
+void ossl_json_bool(OSSL_JSON_ENC *json, int value);
+
+/* Encode a JSON integer from a uint64_t. */
+void ossl_json_u64(OSSL_JSON_ENC *json, uint64_t value);
+
+/* Encode a JSON integer from an int64_t. */
+void ossl_json_i64(OSSL_JSON_ENC *json, int64_t value);
+
+/* Encode a JSON number from a 64-bit floating point value. */
+void ossl_json_f64(OSSL_JSON_ENC *json, double value);
+
+/*
+ * Encode a JSON UTF-8 string from a zero-terminated string. The string passed
+ * can be freed immediately following the call to this function.
+ */
+void ossl_json_str(OSSL_JSON_ENC *json, const char *str);
+
+/*
+ * Encode a JSON UTF-8 string from a string with the given length. The string
+ * passed can be freed immediately following the call to this function.
+ */
+void ossl_json_str_len(OSSL_JSON_ENC *json, const char *str, size_t str_len);
+
+/*
+ * Encode binary data as a lowercase hex string. data_len is the data length in
+ * bytes.
+ */
+void ossl_json_str_hex(OSSL_JSON_ENC *json, const void *data, size_t data_len);
+
+#endif

+ 36 - 2
libs/openssl/include/internal/list.h

@@ -20,6 +20,34 @@
 #  define OSSL_LIST_DBG(x) x;
 # endif
 
+# define LIST_FOREACH_FROM(p, name, init)                                   \
+    for ((p) = (init);                                                      \
+         (p) != NULL;                                                       \
+         (p) = ossl_list_##name##_next(p))
+# define LIST_FOREACH(p, name, l)                                           \
+    LIST_FOREACH_FROM(p, name, ossl_list_##name##_head(l))
+
+# define LIST_FOREACH_REV_FROM(p, name, init)                               \
+    for ((p) = (init);                                                      \
+         (p) != NULL;                                                       \
+         (p) = ossl_list_##name##_prev(p))
+# define LIST_FOREACH_REV(p, name, l)                                       \
+    LIST_FOREACH_FROM(p, name, ossl_list_##name##_tail(l))
+
+# define LIST_FOREACH_DELSAFE_FROM(p, pn, name, init)                       \
+    for ((p) = (init);                                                      \
+         (p) != NULL && (((pn) = ossl_list_##name##_next(p)), 1);           \
+         (p) = (pn))
+#define LIST_FOREACH_DELSAFE(p, pn, name, l)                                \
+    LIST_FOREACH_DELSAFE_FROM(p, pn, name, ossl_list_##name##_head(l))
+
+# define LIST_FOREACH_REV_DELSAFE_FROM(p, pn, name, init)                   \
+    for ((p) = (init);                                                      \
+         (p) != NULL && (((pn) = ossl_list_##name##_prev(p)), 1);           \
+         (p) = (pn))
+# define LIST_FOREACH_REV_DELSAFE(p, pn, name, l)                           \
+    LIST_FOREACH_REV_DELSAFE_FROM(p, pn, name, ossl_list_##name##_tail(l))
+
 /* Define a list structure */
 # define OSSL_LIST(name) OSSL_LIST_ ## name
 
@@ -30,12 +58,14 @@
         OSSL_LIST_DBG(struct ossl_list_st_ ## name *list)                   \
     } ossl_list_ ## name
 
-# define DEFINE_LIST_OF(name, type)                                         \
+# define DECLARE_LIST_OF(name, type)                                        \
     typedef struct ossl_list_st_ ## name OSSL_LIST(name);                   \
     struct ossl_list_st_ ## name {                                          \
         type *alpha, *omega;                                                \
         size_t num_elems;                                                   \
-    };                                                                      \
+    }                                                                       \
+
+# define DEFINE_LIST_OF_IMPL(name, type)                                    \
     static ossl_unused ossl_inline void                                     \
     ossl_list_##name##_init(OSSL_LIST(name) *list)                          \
     {                                                                       \
@@ -166,4 +196,8 @@
     }                                                                       \
     struct ossl_list_st_ ## name
 
+# define DEFINE_LIST_OF(name, type)                                         \
+    DECLARE_LIST_OF(name, type);                                            \
+    DEFINE_LIST_OF_IMPL(name, type)
+
 #endif

+ 131 - 0
libs/openssl/include/internal/qlog.h

@@ -0,0 +1,131 @@
+/*
+ * 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
+ */
+
+#ifndef OSSL_QLOG_H
+# define OSSL_QLOG_H
+
+# include <openssl/ssl.h>
+# include "internal/quic_types.h"
+# include "internal/time.h"
+
+typedef struct qlog_st QLOG;
+
+# ifndef OPENSSL_NO_QLOG
+
+enum {
+    QLOG_EVENT_TYPE_NONE,
+
+#  define QLOG_EVENT(cat, name) QLOG_EVENT_TYPE_##cat##_##name,
+#  include "internal/qlog_events.h"
+#  undef QLOG_EVENT
+
+    QLOG_EVENT_TYPE_NUM
+};
+
+typedef struct qlog_trace_info_st {
+    QUIC_CONN_ID    odcid;
+    const char      *title, *description, *group_id;
+    int             is_server;
+    OSSL_TIME       (*now_cb)(void *arg);
+    void            *now_cb_arg;
+    uint64_t        override_process_id;
+    const char      *override_impl_name;
+} QLOG_TRACE_INFO;
+
+QLOG *ossl_qlog_new(const QLOG_TRACE_INFO *info);
+QLOG *ossl_qlog_new_from_env(const QLOG_TRACE_INFO *info);
+
+void ossl_qlog_free(QLOG *qlog);
+
+/* Configuration */
+int ossl_qlog_set_event_type_enabled(QLOG *qlog, uint32_t event_type,
+                                     int enable);
+int ossl_qlog_set_filter(QLOG *qlog, const char *filter);
+
+int ossl_qlog_set_sink_bio(QLOG *qlog, BIO *bio);
+#  ifndef OPENSSL_NO_STDIO
+int ossl_qlog_set_sink_file(QLOG *qlog, FILE *file, int close_flag);
+#  endif
+int ossl_qlog_set_sink_filename(QLOG *qlog, const char *filename);
+
+/* Operations */
+int ossl_qlog_flush(QLOG *qlog);
+
+/* Queries */
+int ossl_qlog_enabled(QLOG *qlog, uint32_t event_type);
+
+/* Grouping Functions */
+int ossl_qlog_event_try_begin(QLOG *qlog, uint32_t event_type,
+                              const char *event_cat, const char *event_name,
+                              const char *event_combined_name);
+void ossl_qlog_event_end(QLOG *qlog);
+
+void ossl_qlog_group_begin(QLOG *qlog, const char *name);
+void ossl_qlog_group_end(QLOG *qlog);
+
+void ossl_qlog_array_begin(QLOG *qlog, const char *name);
+void ossl_qlog_array_end(QLOG *qlog);
+
+void ossl_qlog_override_time(QLOG *qlog, OSSL_TIME event_time);
+
+/* Grouping Macros */
+#  define QLOG_EVENT_BEGIN(qlog, cat, name)                                 \
+    {                                                                       \
+        QLOG *qlog_instance = (qlog);                                       \
+        uint32_t qlog_event_type = QLOG_EVENT_TYPE_##cat##_##name;          \
+                                                                            \
+        if (ossl_qlog_event_try_begin(qlog_instance, qlog_event_type,       \
+                                      #cat, #name, #cat ":" #name)) {
+
+#  define QLOG_EVENT_END()                                                  \
+            ossl_qlog_event_end(qlog_instance);                             \
+        }                                                                   \
+    }
+
+#  define QLOG_BEGIN(name)                                                  \
+    {                                                                       \
+        ossl_qlog_group_begin(qlog_instance, (name));
+
+#  define QLOG_END()                                                        \
+        ossl_qlog_group_end(qlog_instance);                                 \
+    }
+
+#  define QLOG_BEGIN_ARRAY(name)                                            \
+    {                                                                       \
+        ossl_qlog_array_begin(qlog_instance, (name));
+
+#  define QLOG_END_ARRAY()                                                  \
+        ossl_qlog_array_end(qlog_instance);                                 \
+    }
+
+/* Field Functions */
+void ossl_qlog_str(QLOG *qlog, const char *name, const char *value);
+void ossl_qlog_str_len(QLOG *qlog, const char *name,
+                       const char *value, size_t value_len);
+void ossl_qlog_u64(QLOG *qlog, const char *name, uint64_t value);
+void ossl_qlog_i64(QLOG *qlog, const char *name, int64_t value);
+void ossl_qlog_bool(QLOG *qlog, const char *name, int value);
+void ossl_qlog_bin(QLOG *qlog, const char *name,
+                   const void *value, size_t value_len);
+
+/* Field Macros */
+#  define QLOG_STR(name, value)   ossl_qlog_str(qlog_instance, (name), (value))
+#  define QLOG_STR_LEN(name, value, value_len)                                \
+    ossl_qlog_str_len(qlog_instance, (name), (value), (value_len))
+#  define QLOG_I64(name, value)   ossl_qlog_i64(qlog_instance, (name), (value))
+#  define QLOG_U64(name, value)   ossl_qlog_u64(qlog_instance, (name), (value))
+#  define QLOG_F64(name, value)   ossl_qlog_f64(qlog_instance, (name), (value))
+#  define QLOG_BOOL(name, value)  ossl_qlog_bool(qlog_instance, (name), (value))
+#  define QLOG_BIN(name, value, value_len) \
+    ossl_qlog_bin(qlog_instance, (name), (value), (value_len))
+#  define QLOG_CID(name, value) QLOG_BIN((name), (value)->id, (value)->id_len)
+
+# endif
+
+#endif

+ 56 - 0
libs/openssl/include/internal/qlog_event_helpers.h

@@ -0,0 +1,56 @@
+/*
+ * 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
+ */
+
+#ifndef OSSL_QLOG_EVENT_HELPERS_H
+# define OSSL_QLOG_EVENT_HELPERS_H
+
+# include <openssl/ssl.h>
+# include "internal/qlog.h"
+# include "internal/quic_types.h"
+# include "internal/quic_channel.h"
+# include "internal/quic_txpim.h"
+# include "internal/quic_record_tx.h"
+# include "internal/quic_wire_pkt.h"
+
+/* connectivity:connection_started */
+void ossl_qlog_event_connectivity_connection_started(QLOG *qlog,
+                                                     const QUIC_CONN_ID *init_dcid);
+
+/* connectivity:connection_state_updated */
+void ossl_qlog_event_connectivity_connection_state_updated(QLOG *qlog,
+                                                           uint32_t old_state,
+                                                           uint32_t new_state,
+                                                           int handshake_complete,
+                                                           int handshake_confirmed);
+
+/* connectivity:connection_closed */
+void ossl_qlog_event_connectivity_connection_closed(QLOG *qlog,
+                                                    const QUIC_TERMINATE_CAUSE *tcause);
+
+/* recovery:packet_lost */
+void ossl_qlog_event_recovery_packet_lost(QLOG *qlog,
+                                          const QUIC_TXPIM_PKT *tpkt);
+
+/* transport:packet_sent */
+void ossl_qlog_event_transport_packet_sent(QLOG *qlog,
+                                           const QUIC_PKT_HDR *hdr,
+                                           QUIC_PN pn,
+                                           const OSSL_QTX_IOVEC *iovec,
+                                           size_t numn_iovec,
+                                           uint64_t datagram_id);
+
+/* transport:packet_received */
+void ossl_qlog_event_transport_packet_received(QLOG *qlog,
+                                               const QUIC_PKT_HDR *hdr,
+                                               QUIC_PN pn,
+                                               const OSSL_QTX_IOVEC *iovec,
+                                               size_t numn_iovec,
+                                               uint64_t datagram_id);
+
+#endif

+ 15 - 0
libs/openssl/include/internal/qlog_events.h

@@ -0,0 +1,15 @@
+/*
+ * 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
+ */
+QLOG_EVENT(connectivity, connection_started)
+QLOG_EVENT(connectivity, connection_state_updated)
+QLOG_EVENT(connectivity, connection_closed)
+QLOG_EVENT(transport, parameters_set)
+QLOG_EVENT(transport, packet_sent)
+QLOG_EVENT(transport, packet_received)
+QLOG_EVENT(recovery, packet_lost)

+ 1 - 2
libs/openssl/include/internal/quic_ackm.h

@@ -13,13 +13,12 @@
 # include "internal/quic_cc.h"
 # include "internal/quic_types.h"
 # include "internal/quic_wire.h"
+# include "internal/quic_predef.h"
 # include "internal/time.h"
 # include "internal/list.h"
 
 # ifndef OPENSSL_NO_QUIC
 
-typedef struct ossl_ackm_st OSSL_ACKM;
-
 OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg),
                          void *now_arg,
                          OSSL_STATM *statm,

+ 3 - 4
libs/openssl/include/internal/quic_cc.h

@@ -11,11 +11,10 @@
 
 #include "openssl/params.h"
 #include "internal/time.h"
+#include "internal/quic_predef.h"
 
 # ifndef OPENSSL_NO_QUIC
 
-typedef struct ossl_cc_data_st OSSL_CC_DATA;
-
 typedef struct ossl_cc_ack_info_st {
     /* The time the packet being acknowledged was originally sent. */
     OSSL_TIME   tx_time;
@@ -80,7 +79,7 @@ typedef struct ossl_cc_ecn_info_st {
  */
 #define OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION     (1U << 0)
 
-typedef struct ossl_cc_method_st {
+struct ossl_cc_method_st {
     /*
      * Instantiation.
      */
@@ -209,7 +208,7 @@ typedef struct ossl_cc_method_st {
      */
     int (*on_ecn)(OSSL_CC_DATA *ccdata,
                   const OSSL_CC_ECN_INFO *info);
-} OSSL_CC_METHOD;
+};
 
 extern const OSSL_CC_METHOD ossl_cc_dummy_method;
 extern const OSSL_CC_METHOD ossl_cc_newreno_method;

+ 1 - 1
libs/openssl/include/internal/quic_cfq.h

@@ -12,6 +12,7 @@
 
 # include <openssl/ssl.h>
 # include "internal/quic_types.h"
+# include "internal/quic_predef.h"
 
 # ifndef OPENSSL_NO_QUIC
 
@@ -63,7 +64,6 @@ int ossl_quic_cfq_item_is_unreliable(const QUIC_CFQ_ITEM *item);
  * QUIC Control Frame Queue
  * ========================
  */
-typedef struct quic_cfq_st QUIC_CFQ;
 
 QUIC_CFQ *ossl_quic_cfq_new(void);
 void ossl_quic_cfq_free(QUIC_CFQ *cfq);

+ 63 - 42
libs/openssl/include/internal/quic_channel.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -12,9 +12,10 @@
 
 # include <openssl/ssl.h>
 # include "internal/quic_types.h"
-# include "internal/quic_stream_map.h"
-# include "internal/quic_reactor.h"
-# include "internal/quic_statm.h"
+# include "internal/quic_record_tx.h"
+# include "internal/quic_wire.h"
+# include "internal/quic_predef.h"
+# include "internal/qlog.h"
 # include "internal/time.h"
 # include "internal/thread.h"
 
@@ -106,34 +107,26 @@
 #  define QUIC_CHANNEL_STATE_TERMINATED                  4
 
 typedef struct quic_channel_args_st {
-    OSSL_LIB_CTX    *libctx;
-    const char      *propq;
+    /*
+     * The QUIC_PORT which the channel is to belong to. The lifetime of the
+     * QUIC_PORT must exceed that of the created channel.
+     */
+    QUIC_PORT       *port;
+    /* LCIDM to register LCIDs with. */
+    QUIC_LCIDM      *lcidm;
+    /* SRTM to register SRTs with. */
+    QUIC_SRTM       *srtm;
+
     int             is_server;
     SSL             *tls;
 
-    /*
-     * This must be a mutex the lifetime of which will exceed that of the
-     * channel. The instantiator of the channel is responsible for providing a
-     * mutex as this makes it easier to handle instantiation and teardown of
-     * channels in situations potentially requiring locking.
-     *
-     * Note that this is a MUTEX not a RWLOCK as it needs to be an OS mutex for
-     * compatibility with an OS's condition variable wait API, whereas RWLOCK
-     * may, depending on the build configuration, be implemented using an OS's
-     * mutex primitive or using its RW mutex primitive.
-     */
-    CRYPTO_MUTEX    *mutex;
+    /* Whether to use qlog. */
+    int             use_qlog;
 
-    /*
-     * Optional function pointer to use to retrieve the current time. If NULL,
-     * ossl_time_now() is used.
-     */
-    OSSL_TIME       (*now_cb)(void *arg);
-    void            *now_cb_arg;
+    /* Title to use for the qlog session, or NULL. */
+    const char      *qlog_title;
 } QUIC_CHANNEL_ARGS;
 
-typedef struct quic_channel_st QUIC_CHANNEL;
-
 /* Represents the cause for a connection's termination. */
 typedef struct quic_terminate_cause_st {
     /*
@@ -176,10 +169,11 @@ typedef struct quic_terminate_cause_st {
     unsigned int                    remote : 1;
 } QUIC_TERMINATE_CAUSE;
 
-
 /*
  * Create a new QUIC channel using the given arguments. The argument structure
  * does not need to remain allocated. Returns NULL on failure.
+ *
+ * Only QUIC_PORT should use this function.
  */
 QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args);
 
@@ -276,6 +270,23 @@ void ossl_quic_channel_on_remote_conn_close(QUIC_CHANNEL *ch,
 void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch,
                                       OSSL_QUIC_FRAME_NEW_CONN_ID *f);
 
+/* Temporarily exposed during QUIC_PORT transition. */
+int ossl_quic_channel_on_new_conn(QUIC_CHANNEL *ch, const BIO_ADDR *peer,
+                                  const QUIC_CONN_ID *peer_scid,
+                                  const QUIC_CONN_ID *peer_dcid);
+
+/* For use by QUIC_PORT. You should not need to call this directly. */
+void ossl_quic_channel_subtick(QUIC_CHANNEL *ch, QUIC_TICK_RESULT *r,
+                               uint32_t flags);
+
+/* For use by QUIC_PORT only. */
+void ossl_quic_channel_raise_net_error(QUIC_CHANNEL *ch);
+
+/* For use by QUIC_PORT only. */
+void ossl_quic_channel_on_stateless_reset(QUIC_CHANNEL *ch);
+
+void ossl_quic_channel_inject(QUIC_CHANNEL *ch, QUIC_URXE *e);
+
 /*
  * Queries and Accessors
  * =====================
@@ -297,18 +308,6 @@ OSSL_STATM *ossl_quic_channel_get_statm(QUIC_CHANNEL *ch);
 int ossl_quic_channel_get_peer_addr(QUIC_CHANNEL *ch, BIO_ADDR *peer_addr);
 int ossl_quic_channel_set_peer_addr(QUIC_CHANNEL *ch, const BIO_ADDR *peer_addr);
 
-/* Gets/sets the underlying network read and write BIOs. */
-BIO *ossl_quic_channel_get_net_rbio(QUIC_CHANNEL *ch);
-BIO *ossl_quic_channel_get_net_wbio(QUIC_CHANNEL *ch);
-int ossl_quic_channel_set_net_rbio(QUIC_CHANNEL *ch, BIO *net_rbio);
-int ossl_quic_channel_set_net_wbio(QUIC_CHANNEL *ch, BIO *net_wbio);
-
-/*
- * Re-poll the network BIOs already set to determine if their support
- * for polling has changed.
- */
-int ossl_quic_channel_update_poll_descriptors(QUIC_CHANNEL *ch);
-
 /*
  * Returns an existing stream by stream ID. Returns NULL if the stream does not
  * exist.
@@ -326,6 +325,8 @@ int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch);
 int ossl_quic_channel_is_handshake_complete(const QUIC_CHANNEL *ch);
 int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch);
 
+QUIC_PORT *ossl_quic_channel_get0_port(QUIC_CHANNEL *ch);
+QUIC_ENGINE *ossl_quic_channel_get0_engine(QUIC_CHANNEL *ch);
 QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch);
 
 SSL *ossl_quic_channel_get0_ssl(QUIC_CHANNEL *ch);
@@ -404,9 +405,6 @@ int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch);
 /* Force transmission of an ACK-eliciting packet. */
 int ossl_quic_channel_ping(QUIC_CHANNEL *ch);
 
-/* For testing use. While enabled, ticking is not performed. */
-void ossl_quic_channel_set_inhibit_tick(QUIC_CHANNEL *ch, int inhibit);
-
 /*
  * These queries exist for diagnostic purposes only. They may roll over.
  * Do not rely on them for non-testing purposes.
@@ -424,6 +422,29 @@ void ossl_quic_channel_get_diag_local_cid(QUIC_CHANNEL *ch, QUIC_CONN_ID *cid);
  */
 int ossl_quic_channel_is_new_local_stream_admissible(QUIC_CHANNEL *ch, int is_uni);
 
+/*
+ * Returns the number of additional streams that can currently be created based
+ * on flow control.
+ */
+uint64_t ossl_quic_channel_get_local_stream_count_avail(const QUIC_CHANNEL *ch,
+                                                        int is_uni);
+uint64_t ossl_quic_channel_get_remote_stream_count_avail(const QUIC_CHANNEL *ch,
+                                                         int is_uni);
+
+/*
+ * Returns 1 if we have generated our local transport parameters yet.
+ */
+int ossl_quic_channel_have_generated_transport_params(const QUIC_CHANNEL *ch);
+
+/* Configures the idle timeout to request from peer (milliseconds, 0=no timeout). */
+void ossl_quic_channel_set_max_idle_timeout_request(QUIC_CHANNEL *ch, uint64_t ms);
+/* Get the configured idle timeout to request from peer. */
+uint64_t ossl_quic_channel_get_max_idle_timeout_request(const QUIC_CHANNEL *ch);
+/* Get the idle timeout requested by the peer. */
+uint64_t ossl_quic_channel_get_max_idle_timeout_peer_request(const QUIC_CHANNEL *ch);
+/* Get the idle timeout actually negotiated. */
+uint64_t ossl_quic_channel_get_max_idle_timeout_actual(const QUIC_CHANNEL *ch);
+
 # endif
 
 #endif

+ 26 - 86
libs/openssl/include/internal/quic_demux.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -12,6 +12,7 @@
 
 # include <openssl/ssl.h>
 # include "internal/quic_types.h"
+# include "internal/quic_predef.h"
 # include "internal/bio_addr.h"
 # include "internal/time.h"
 # include "internal/list.h"
@@ -23,20 +24,19 @@
  * ============
  *
  * The QUIC connection demuxer is the entity responsible for receiving datagrams
- * from the network via a datagram BIO. It parses packet headers to determine
- * each packet's destination connection ID (DCID) and hands off processing of
- * the packet to the correct QUIC Record Layer (QRL)'s RX side (known as the
- * QRX).
- *
- * A QRX is instantiated per QUIC connection and contains the cryptographic
- * resources needed to decrypt QUIC packets for that connection. Received
- * datagrams are passed from the demuxer to the QRX via a callback registered
- * for a specific DCID by the QRX; thus the demuxer has no specific knowledge of
- * the QRX and is not coupled to it.
- *
- * A connection may have multiple connection IDs associated with it; a QRX
- * handles this simply by registering multiple connection IDs with the demuxer
- * via multiple register calls.
+ * from the network via a datagram BIO. It parses the headers of the first
+ * packet in the datagram to determine that packet's DCID and hands off
+ * processing of the entire datagram to a single callback function which can
+ * decide how to handle and route the datagram, for example by looking up
+ * a QRX instance and injecting the URXE into that QRX.
+ *
+ * A QRX will typically be instantiated per QUIC connection and contains the
+ * cryptographic resources needed to decrypt QUIC packets for that connection.
+ * However, it is up to the callback function to handle routing, for example by
+ * consulting a LCIDM instance. Thus the demuxer has no specific knowledge of
+ * any QRX and is not coupled to it. All CID knowledge is also externalised into
+ * a LCIDM or other CID state tracking object, without the DEMUX being coupled
+ * to any particular DCID resolution mechanism.
  *
  * URX Queue
  * ---------
@@ -83,8 +83,6 @@
  * same allocation.
  */
 
-typedef struct quic_urxe_st QUIC_URXE;
-
 /* Maximum number of packets we allow to exist in one datagram. */
 #define QUIC_MAX_PKT_PER_URXE       (sizeof(uint64_t) * 8)
 
@@ -108,6 +106,12 @@ struct quic_urxe_st {
      */
     uint64_t        processed, hpr_removed;
 
+    /*
+     * This monotonically increases with each datagram received. It is used for
+     * diagnostic purposes only.
+     */
+    uint64_t        datagram_id;
+
     /*
      * Address of peer we received the datagram from, and the local interface
      * address we received it on. If local address support is not enabled, local
@@ -159,9 +163,6 @@ void ossl_quic_urxe_remove(QUIC_URXE_LIST *l, QUIC_URXE *e);
 void ossl_quic_urxe_insert_head(QUIC_URXE_LIST *l, QUIC_URXE *e);
 void ossl_quic_urxe_insert_tail(QUIC_URXE_LIST *l, QUIC_URXE *e);
 
-/* Opaque type representing a demuxer. */
-typedef struct quic_demux_st QUIC_DEMUX;
-
 /*
  * Called when a datagram is received for a given connection ID.
  *
@@ -169,6 +170,9 @@ typedef struct quic_demux_st QUIC_DEMUX;
  * to mutate this buffer; once the demuxer calls this callback, it will never
  * read the buffer again.
  *
+ * If a DCID was identified for the datagram, dcid is non-NULL; otherwise
+ * it is NULL.
+ *
  * The callee must arrange for ossl_quic_demux_release_urxe or
  * ossl_quic_demux_reinject_urxe to be called on the URXE at some point in the
  * future (this need not be before the callback returns).
@@ -176,15 +180,8 @@ typedef struct quic_demux_st QUIC_DEMUX;
  * At the time the callback is made, the URXE will not be in any queue,
  * therefore the callee can use the prev and next fields as it wishes.
  */
-typedef void (ossl_quic_demux_cb_fn)(QUIC_URXE *e, void *arg);
-
-/*
- * Called when a datagram is received.
- * Returns 1 if the datagram ends with a stateless reset token and
- * 0 if not.
- */
-typedef int (ossl_quic_stateless_reset_cb_fn)(const unsigned char *data,
-                                              size_t data_len, void *arg);
+typedef void (ossl_quic_demux_cb_fn)(QUIC_URXE *e, void *arg,
+                                     const QUIC_CONN_ID *dcid);
 
 /*
  * Creates a new demuxer. The given BIO is used to receive datagrams from the
@@ -220,50 +217,6 @@ void ossl_quic_demux_set_bio(QUIC_DEMUX *demux, BIO *net_bio);
  */
 int ossl_quic_demux_set_mtu(QUIC_DEMUX *demux, unsigned int mtu);
 
-/*
- * Register a datagram handler callback for a connection ID.
- *
- * ossl_quic_demux_pump will call the specified function if it receives a datagram
- * the first packet of which has the specified destination connection ID.
- *
- * It is assumed all packets in a datagram have the same destination connection
- * ID (as QUIC mandates this), but it is the user's responsibility to check for
- * this and reject subsequent packets in a datagram that violate this rule.
- *
- * dst_conn_id is a destination connection ID; it is copied and need not remain
- * valid after this function returns.
- *
- * cb_arg is passed to cb when it is called. For information on the callback,
- * see its typedef above.
- *
- * Only one handler can be set for a given connection ID. If a handler is
- * already set for the given connection ID, returns 0.
- *
- * Returns 1 on success or 0 on failure.
- */
-int ossl_quic_demux_register(QUIC_DEMUX *demux,
-                             const QUIC_CONN_ID *dst_conn_id,
-                             ossl_quic_demux_cb_fn *cb,
-                             void *cb_arg);
-
-/*
- * Unregisters any datagram handler callback set for the given connection ID.
- * Fails if no handler is registered for the given connection ID.
- *
- * Returns 1 on success or 0 on failure.
- */
-int ossl_quic_demux_unregister(QUIC_DEMUX *demux,
-                               const QUIC_CONN_ID *dst_conn_id);
-
-/*
- * Unregisters any datagram handler callback from all connection IDs it is used
- * for. cb and cb_arg must both match the values passed to
- * ossl_quic_demux_register.
- */
-void ossl_quic_demux_unregister_by_cb(QUIC_DEMUX *demux,
-                                      ossl_quic_demux_cb_fn *cb,
-                                      void *cb_arg);
-
 /*
  * Set the default packet handler. This is used for incoming packets which don't
  * match a registered DCID. This is only needed for servers. If a default packet
@@ -278,18 +231,6 @@ void ossl_quic_demux_set_default_handler(QUIC_DEMUX *demux,
                                          ossl_quic_demux_cb_fn *cb,
                                          void *cb_arg);
 
-/*
- * Sets a callback for stateless reset processing.
- *
- * If set, this callback is called for datagrams for which we cannot identify
- * a CID.  This function should return 1 if there is a stateless reset token
- * present and 0 if not.  If there is a token present, the connection should
- * also be reset.
- */
-void ossl_quic_demux_set_stateless_reset_handler(
-        QUIC_DEMUX *demux,
-        ossl_quic_stateless_reset_cb_fn *cb, void *cb_arg);
-
 /*
  * Releases a URXE back to the demuxer. No reference must be made to the URXE or
  * its buffer after calling this function. The URXE must not be in any queue;
@@ -335,7 +276,6 @@ void ossl_quic_demux_reinject_urxe(QUIC_DEMUX *demux,
 #define QUIC_DEMUX_PUMP_RES_OK              1
 #define QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL  (-1)
 #define QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL  (-2)
-#define QUIC_DEMUX_PUMP_RES_STATELESS_RESET (-3)
 
 int ossl_quic_demux_pump(QUIC_DEMUX *demux);
 

+ 84 - 0
libs/openssl/include/internal/quic_engine.h

@@ -0,0 +1,84 @@
+/*
+ * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+#ifndef OSSL_QUIC_ENGINE_H
+# define OSSL_QUIC_ENGINE_H
+
+# include <openssl/ssl.h>
+
+# include "internal/quic_predef.h"
+# include "internal/quic_port.h"
+# include "internal/thread_arch.h"
+
+# ifndef OPENSSL_NO_QUIC
+
+/*
+ * QUIC Engine
+ * ===========
+ *
+ * A QUIC Engine (QUIC_ENGINE) represents an event processing domain for the
+ * purposes of QUIC and contains zero or more subsidiary QUIC_PORT instances
+ * (each of which currently represents a UDP socket), each of which in turn
+ * contains zero or more subsidiary QUIC_CHANNEL instances, each of which
+ * represents a single QUIC connection. All QUIC_PORT instances must belong
+ * to a QUIC_ENGINE.
+ *
+ * TODO(QUIC SERVER): Currently a QUIC_PORT belongs to a single QUIC_CHANNEL.
+ * This will cease to be the case once connection migration and/or multipath is
+ * implemented, so in future a channel might be associated with multiple ports.
+ *
+ * A QUIC engine is the root object in a QUIC event domain, and is responsible
+ * for managing event processing for all QUIC ports and channels (e.g. timeouts,
+ * clock management, the QUIC_REACTOR instance, etc.).
+ */
+typedef struct quic_engine_args_st {
+    OSSL_LIB_CTX    *libctx;
+    const char      *propq;
+
+    /*
+     * This must be a mutex the lifetime of which will exceed that of the engine
+     * and all ports and channels. The instantiator of the engine is responsible
+     * for providing a mutex as this makes it easier to handle instantiation and
+     * teardown of channels in situations potentially requiring locking.
+     *
+     * Note that this is a MUTEX not a RWLOCK as it needs to be an OS mutex for
+     * compatibility with an OS's condition variable wait API, whereas RWLOCK
+     * may, depending on the build configuration, be implemented using an OS's
+     * mutex primitive or using its RW mutex primitive.
+     */
+    CRYPTO_MUTEX    *mutex;
+
+    OSSL_TIME       (*now_cb)(void *arg);
+    void            *now_cb_arg;
+} QUIC_ENGINE_ARGS;
+
+QUIC_ENGINE *ossl_quic_engine_new(const QUIC_ENGINE_ARGS *args);
+
+void ossl_quic_engine_free(QUIC_ENGINE *qeng);
+
+/*
+ * Create a port which is a child of the engine. args->engine shall be NULL.
+ */
+QUIC_PORT *ossl_quic_engine_create_port(QUIC_ENGINE *qeng,
+                                        const QUIC_PORT_ARGS *args);
+
+/* Gets the mutex used by the engine. */
+CRYPTO_MUTEX *ossl_quic_engine_get0_mutex(QUIC_ENGINE *qeng);
+
+/* Gets the current time. */
+OSSL_TIME ossl_quic_engine_get_time(QUIC_ENGINE *qeng);
+
+/* For testing use. While enabled, ticking is not performed. */
+void ossl_quic_engine_set_inhibit_tick(QUIC_ENGINE *qeng, int inhibit);
+
+/* Gets the reactor which can be used to tick/poll on the port. */
+QUIC_REACTOR *ossl_quic_engine_get0_reactor(QUIC_ENGINE *qeng);
+
+# endif
+
+#endif

+ 10 - 4
libs/openssl/include/internal/quic_fc.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-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
@@ -229,20 +229,26 @@ int ossl_quic_rxfc_on_retire(QUIC_RXFC *rxfc,
  *
  * This value increases monotonically.
  */
-uint64_t ossl_quic_rxfc_get_cwm(QUIC_RXFC *rxfc);
+uint64_t ossl_quic_rxfc_get_cwm(const QUIC_RXFC *rxfc);
 
 /*
  * Returns the current SWM. This is the total number of bytes the peer has
  * transmitted to us. This is intended for diagnostic use only; you should
  * not need it.
  */
-uint64_t ossl_quic_rxfc_get_swm(QUIC_RXFC *rxfc);
+uint64_t ossl_quic_rxfc_get_swm(const QUIC_RXFC *rxfc);
 
 /*
  * Returns the current RWM. This is the total number of bytes that has been
  * retired. This is intended for diagnostic use only; you should not need it.
  */
-uint64_t ossl_quic_rxfc_get_rwm(QUIC_RXFC *rxfc);
+uint64_t ossl_quic_rxfc_get_rwm(const QUIC_RXFC *rxfc);
+
+/*
+ * Returns the current credit. This is the CWM minus the SWM. This is intended
+ * for diagnostic use only; you should not need it.
+ */
+uint64_t ossl_quic_rxfc_get_credit(const QUIC_RXFC *rxfc);
 
 /*
  * Returns the CWM changed flag. If clear is 1, the flag is cleared and the old

+ 257 - 0
libs/openssl/include/internal/quic_lcidm.h

@@ -0,0 +1,257 @@
+/*
+* Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+*
+* Licensed under the Apache License 2.0 (the "License").  You may not use
+* this file except in compliance with the License.  You can obtain a copy
+* in the file LICENSE in the source distribution or at
+* https://www.openssl.org/source/license.html
+*/
+
+#ifndef OSSL_INTERNAL_QUIC_LCIDM_H
+# define OSSL_INTERNAL_QUIC_LCIDM_H
+# pragma once
+
+# include "internal/e_os.h"
+# include "internal/time.h"
+# include "internal/quic_types.h"
+# include "internal/quic_wire.h"
+# include "internal/quic_predef.h"
+
+# ifndef OPENSSL_NO_QUIC
+
+/*
+ * QUIC Local Connection ID Manager
+ * ================================
+ *
+ * This manages connection IDs for the RX side, which is to say that it issues
+ * local CIDs (LCIDs) to a peer which that peer can then use to address us via a
+ * packet DCID. This is as opposed to CID management for the TX side, which
+ * determines which CIDs we use to transmit based on remote CIDs (RCIDs) the
+ * peer sent to us.
+ *
+ * An opaque pointer can be associated with each LCID. Pointer identity
+ * (equality) is used to distinguish distinct connections.
+ *
+ * LCIDs fall into three categories:
+ *
+ *   1. A client's Initial ODCID                       (1)
+ *   2. Our local Initial SCID                         (1)
+ *   3. A CID issued via a NEW_CONNECTION_ID frame     (n)
+ *   4. A server's Retry SCID                          (0..1)
+ *
+ * (1) is enrolled using ossl_quic_lcidm_enrol_odcid() and retired by the time
+ * of handshake completion at the latest. It is needed in case the first
+ * response packet from a server is lost and the client keeps using its Initial
+ * ODCID. There is never more than one of these, and no sequence number is
+ * associated with this temporary LCID.
+ *
+ * (2) is created by a client when it begins connecting, or by a server when it
+ * responds to a new connection request. In the latter case, it is generated by
+ * the server as the preferred DCID for traffic directed towards it. A client
+ * should switch to using this as a RCID as soon as it receives a valid packet
+ * from the server. This LCID has a sequence number of 0.
+ *
+ * (3) is created when we issue a NEW_CONNECTION_ID frame. Arbitrarily many of
+ * these can exist.
+ *
+ * (4) is a special case. When a server issues a retry it generates a new SCID
+ * much as it does for (2). However since retries are supposed to be stateless,
+ * we don't actually register it as an LCID. When the client subsequently
+ * replies with an Initial packet with token in response to the Retry, the
+ * server will handle this as a new connection attempt due to not recognising
+ * the DCID, which is what we want anyway. (The Retry SCID is subsequently
+ * validated as matching the new Initial ODCID via attestation in the encrypted
+ * contents of the opaque retry token.) Thus, the LCIDM is not actually involved
+ * at all here.
+ *
+ * Retirement is as follows:
+ *
+ * (1) is retired automatically when we know it won't be needed anymore. This is
+ * when the handshake is completed at the latest, and could potentially be
+ * earlier.
+ *
+ * Both (2) and (3) are retired normally via RETIRE_CONNECTION_ID frames, as it
+ * has a sequence number of 0.
+ *
+ *
+ * ODCID Peculiarities
+ * -------------------
+ *
+ * Almost all LCIDs are issued by the receiver responsible for routing them,
+ * which means that almost all LCIDs will have the same length (specified in
+ * lcid_len below). The only exception to this is (1); the ODCID is the only
+ * case where we recognise an LCID we didn't ourselves generate. Since an ODCID
+ * is chosen by the peer, it can be any length and doesn't necessarily match the
+ * length we use for LCIDs we generate ourselves.
+ *
+ * Since DCID decoding for short-header packets requires an implicitly known
+ * DCID length, it logically follows that an ODCID can never be used in a 1-RTT
+ * packet. This is fine as by the time the 1-RTT EL is reached the peer should
+ * already have switched away from the ODCID to a CID we generated ourselves,
+ * and if this has not happened we can consider that a protocol violation.
+ *
+ * In any case, this means that the LCIDM must necessarily support LCIDs of
+ * different lengths, even if it always generates LCIDs of a given length.
+ *
+ * An ODCID has no sequence number associated with it. It is the only CID to
+ * lack one.
+ */
+
+/*
+ * Creates a new LCIDM. lcid_len is the length to use for LCIDs in bytes, which
+ * may be zero.
+ *
+ * Returns NULL on failure.
+ */
+QUIC_LCIDM *ossl_quic_lcidm_new(OSSL_LIB_CTX *libctx, size_t lcid_len);
+
+/* Frees a LCIDM. */
+void ossl_quic_lcidm_free(QUIC_LCIDM *lcidm);
+
+/* Gets the local CID length this LCIDM was configured to use. */
+size_t ossl_quic_lcidm_get_lcid_len(const QUIC_LCIDM *lcidm);
+
+/*
+ * Determines the number of active LCIDs (i.e,. LCIDs which can be used for
+ * reception) currently associated with the given opaque pointer.
+ */
+size_t ossl_quic_lcidm_get_num_active_lcid(const QUIC_LCIDM *lcidm,
+                                           void *opaque);
+
+/*
+ * Enrol an Initial ODCID sent by the peer. This is the DCID in the first
+ * Initial packet sent by a client. When we receive a client's first Initial
+ * packet, we immediately respond with our own SCID (generated using
+ * ossl_quic_lcidm_generate_initial) to tell the client to switch to using that,
+ * so ideally the ODCID will only be used for a single packet. However since
+ * that response might be lost, we also need to accept additional packets using
+ * the ODCID and need to make sure they get routed to the same connection and
+ * not interpreted as another new connection attempt. Thus before the CID
+ * switchover is confirmed, we also have to handle incoming packets addressed to
+ * the ODCID. This function is used to temporarily enroll the ODCID for a
+ * connection. Such a LCID is considered to have a sequence number of
+ * LCIDM_ODCID_SEQ_NUM internally for our purposes.
+ *
+ * Note that this is the *only* circumstance where we recognise an LCID we did
+ * not generate ourselves, or allow an LCID with a different length to lcid_len.
+ *
+ * An ODCID MUST be at least 8 bytes in length (RFC 9000 s. 7.2).
+ *
+ * This function may only be called once for a given connection.
+ * Returns 1 on success or 0 on failure.
+ */
+int ossl_quic_lcidm_enrol_odcid(QUIC_LCIDM *lcidm, void *opaque,
+                                const QUIC_CONN_ID *initial_odcid);
+
+/*
+ * Retire a previously enrolled ODCID for a connection. This is generally done
+ * when we know the peer won't be using it any more (when the handshake is
+ * completed at the absolute latest, possibly earlier).
+ *
+ * Returns 1 if there was an enrolled ODCID which was retired and 0 if there was
+ * not or on other failure.
+ */
+int ossl_quic_lcidm_retire_odcid(QUIC_LCIDM *lcidm, void *opaque);
+
+/*
+ * Create the first LCID for a given opaque pointer. The generated LCID is
+ * written to *initial_lcid and associated with the given opaque pointer.
+ *
+ * After this function returns successfully, the caller can for example
+ * register the new LCID with a DEMUX.
+ *
+ * May not be called more than once for a given opaque pointer value.
+ */
+int ossl_quic_lcidm_generate_initial(QUIC_LCIDM *lcidm,
+                                     void *opaque,
+                                     QUIC_CONN_ID *initial_lcid);
+
+/*
+ * Create a subsequent LCID for a given opaque pointer. The information needed
+ * for a NEW_CONN_ID frame informing the peer of the new LCID, including the
+ * LCID itself, is written to *ncid_frame.
+ *
+ * ncid_frame->stateless_reset is not initialised and the caller is responsible
+ * for setting it.
+ *
+ * After this function returns successfully, the caller can for example
+ * register the new LCID with a DEMUX and queue the NEW_CONN_ID frame.
+ */
+int ossl_quic_lcidm_generate(QUIC_LCIDM *lcidm,
+                             void *opaque,
+                             OSSL_QUIC_FRAME_NEW_CONN_ID *ncid_frame);
+
+/*
+ * Retire up to one LCID for a given opaque pointer value. Called repeatedly to
+ * handle a RETIRE_CONN_ID frame.
+ *
+ * If containing_pkt_dcid is non-NULL, this function enforces the requirement
+ * that a CID not be retired by a packet using that CID as the DCID. If
+ * containing_pkt_dcid is NULL, this check is skipped.
+ *
+ * If a LCID is retired as a result of a call to this function, the LCID which
+ * was retired is written to *retired_lcid, the sequence number of the LCID is
+ * written to *retired_seq_num and *did_retire is set to 1. Otherwise,
+ * *did_retire is set to 0. This enables a caller to e.g. unregister the LCID
+ * from a DEMUX. A caller should call this function repeatedly until the
+ * function returns with *did_retire set to 0.
+ *
+ * This call is likely to cause the value returned by
+ * ossl_quic_lcidm_get_num_active_lcid() to go down. A caller may wish to call
+ * ossl_quic_lcidm_generate() repeatedly to bring the number of active LCIDs
+ * back up to some threshold in response after calling this function.
+ *
+ * Returns 1 on success and 0 on failure. If arguments are valid but zero LCIDs
+ * are retired, this is considered a success condition.
+ */
+int ossl_quic_lcidm_retire(QUIC_LCIDM *lcidm,
+                           void *opaque,
+                           uint64_t retire_prior_to,
+                           const QUIC_CONN_ID *containing_pkt_dcid,
+                           QUIC_CONN_ID *retired_lcid,
+                           uint64_t *retired_seq_num,
+                           int *did_retire);
+
+/*
+ * Cull all LCIDM state relating to a given opaque pointer value. This is useful
+ * if connection state is spontaneously freed. The caller is responsible for
+ * e.g. DEMUX state updates.
+ */
+int ossl_quic_lcidm_cull(QUIC_LCIDM *lcidm, void *opaque);
+
+/*
+ * Lookup a LCID. If the LCID is found, writes the associated opaque pointer to
+ * *opaque and the associated sequence number to *seq_num. Returns 1 on success
+ * and 0 if an entry is not found. An output argument may be set to NULL if its
+ * value is not required.
+ *
+ * If the LCID is for an Initial ODCID, *seq_num is set to
+ * LCIDM_ODCID_SEQ_NUM.
+ */
+#define LCIDM_ODCID_SEQ_NUM     UINT64_MAX
+
+int ossl_quic_lcidm_lookup(QUIC_LCIDM *lcidm,
+                           const QUIC_CONN_ID *lcid,
+                           uint64_t *seq_num,
+                           void **opaque);
+
+/*
+ * Debug call to manually remove a specific LCID. Should not be needed in normal
+ * usage. Returns 1 if the LCID was successfully found and removed and 0
+ * otherwise.
+ */
+int ossl_quic_lcidm_debug_remove(QUIC_LCIDM *lcidm,
+                                 const QUIC_CONN_ID *lcid);
+
+/*
+ * Debug call to manually add a numbered LCID with a specific CID value and
+ * sequence number. Should not be needed in normal usage. Returns 1 on success
+ * and 0 on failure.
+ */
+int ossl_quic_lcidm_debug_add(QUIC_LCIDM *lcidm, void *opaque,
+                              const QUIC_CONN_ID *lcid,
+                              uint64_t seq_num);
+
+# endif
+
+#endif

+ 142 - 0
libs/openssl/include/internal/quic_port.h

@@ -0,0 +1,142 @@
+/*
+ * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+#ifndef OSSL_QUIC_PORT_H
+# define OSSL_QUIC_PORT_H
+
+# include <openssl/ssl.h>
+# include "internal/quic_types.h"
+# include "internal/quic_reactor.h"
+# include "internal/quic_demux.h"
+# include "internal/quic_predef.h"
+# include "internal/thread_arch.h"
+
+# ifndef OPENSSL_NO_QUIC
+
+/*
+ * QUIC Port
+ * =========
+ *
+ * A QUIC Port (QUIC_PORT) represents a single UDP network socket and contains
+ * zero or more subsidiary QUIC_CHANNEL instances, each of which represents a
+ * single QUIC connection. All QUIC_CHANNEL instances must belong to a
+ * QUIC_PORT.
+ *
+ * A QUIC port is responsible for managing a set of channels which all use the
+ * same UDP socket, and (in future) for automatically creating new channels when
+ * incoming connections are received.
+ *
+ * In order to retain compatibility with QUIC_TSERVER, it also supports a point
+ * of legacy compatibility where a caller can create an incoming (server role)
+ * channel and that channel will be automatically be bound to the next incoming
+ * connection. In the future this will go away once QUIC_TSERVER is removed.
+ *
+ * All QUIC_PORT instances are created by a QUIC_ENGINE.
+ */
+typedef struct quic_port_args_st {
+    /* The engine which the QUIC port is to be a child of. */
+    QUIC_ENGINE     *engine;
+
+    /*
+     * This SSL_CTX will be used when constructing the handshake layer object
+     * inside newly created channels.
+     */
+    SSL_CTX         *channel_ctx;
+
+    /*
+     * If 1, this port is to be used for multiple connections, so
+     * non-zero-length CIDs should be used. If 0, this port will only be used
+     * for a single connection, so a zero-length local CID can be used.
+     */
+    int             is_multi_conn;
+} QUIC_PORT_ARGS;
+
+/* Only QUIC_ENGINE should use this function. */
+QUIC_PORT *ossl_quic_port_new(const QUIC_PORT_ARGS *args);
+
+void ossl_quic_port_free(QUIC_PORT *port);
+
+/*
+ * Operations
+ * ==========
+ */
+
+/* Create an outgoing channel using this port. */
+QUIC_CHANNEL *ossl_quic_port_create_outgoing(QUIC_PORT *port, SSL *tls);
+
+/*
+ * Create an incoming channel using this port.
+ *
+ * TODO(QUIC SERVER): temporary TSERVER use only - will be removed.
+ */
+QUIC_CHANNEL *ossl_quic_port_create_incoming(QUIC_PORT *port, SSL *tls);
+
+/*
+ * Queries and Accessors
+ * =====================
+ */
+
+/* Gets/sets the underlying network read and write BIO. */
+BIO *ossl_quic_port_get_net_rbio(QUIC_PORT *port);
+BIO *ossl_quic_port_get_net_wbio(QUIC_PORT *port);
+int ossl_quic_port_set_net_rbio(QUIC_PORT *port, BIO *net_rbio);
+int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio);
+
+/*
+ * Re-poll the network BIOs already set to determine if their support
+ * for polling has changed.
+ */
+int ossl_quic_port_update_poll_descriptors(QUIC_PORT *port);
+
+/* Gets the engine which this port is a child of. */
+QUIC_ENGINE *ossl_quic_port_get0_engine(QUIC_PORT *port);
+
+/* Gets the reactor which can be used to tick/poll on the port. */
+QUIC_REACTOR *ossl_quic_port_get0_reactor(QUIC_PORT *port);
+
+/* Gets the demuxer belonging to the port. */
+QUIC_DEMUX *ossl_quic_port_get0_demux(QUIC_PORT *port);
+
+/* Gets the mutex used by the port. */
+CRYPTO_MUTEX *ossl_quic_port_get0_mutex(QUIC_PORT *port);
+
+/* Gets the current time. */
+OSSL_TIME ossl_quic_port_get_time(QUIC_PORT *port);
+
+int ossl_quic_port_get_rx_short_dcid_len(const QUIC_PORT *port);
+int ossl_quic_port_get_tx_init_dcid_len(const QUIC_PORT *port);
+
+/* Returns 1 if the port is running/healthy, 0 if it has failed. */
+int ossl_quic_port_is_running(const QUIC_PORT *port);
+
+/*
+ * Restores port-level error to the error stack. To be called only if
+ * the port is no longer running.
+ */
+void ossl_quic_port_restore_err_state(const QUIC_PORT *port);
+
+/* For use by QUIC_ENGINE. You should not need to call this directly. */
+void ossl_quic_port_subtick(QUIC_PORT *port, QUIC_TICK_RESULT *r,
+                            uint32_t flags);
+
+/*
+ * Events
+ * ======
+ */
+
+/*
+ * Called if a permanent network error occurs. Terminates all channels
+ * immediately. triggering_ch is an optional argument designating
+ * a channel which encountered the network error.
+ */
+void ossl_quic_port_raise_net_error(QUIC_PORT *port,
+                                    QUIC_CHANNEL *triggering_ch);
+
+# endif
+
+#endif

+ 43 - 0
libs/openssl/include/internal/quic_predef.h

@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_QUIC_PREDEF_H
+# define OSSL_QUIC_PREDEF_H
+
+# ifndef OPENSSL_NO_QUIC
+
+typedef struct quic_port_st QUIC_PORT;
+typedef struct quic_channel_st QUIC_CHANNEL;
+typedef struct quic_tls_st QUIC_TLS;
+typedef struct quic_txpim_st QUIC_TXPIM;
+typedef struct quic_fifd_st QUIC_FIFD;
+typedef struct quic_cfq_st QUIC_CFQ;
+typedef struct ossl_quic_tx_packetiser_st OSSL_QUIC_TX_PACKETISER;
+typedef struct ossl_ackm_st OSSL_ACKM;
+typedef struct quic_srt_elem_st QUIC_SRT_ELEM;
+typedef struct ossl_cc_data_st OSSL_CC_DATA;
+typedef struct ossl_cc_method_st OSSL_CC_METHOD;
+typedef struct quic_stream_map_st QUIC_STREAM_MAP;
+typedef struct quic_stream_st QUIC_STREAM;
+typedef struct quic_sstream_st QUIC_SSTREAM;
+typedef struct quic_rstream_st QUIC_RSTREAM;
+typedef struct quic_reactor_st QUIC_REACTOR;
+typedef struct ossl_statm_st OSSL_STATM;
+typedef struct quic_demux_st QUIC_DEMUX;
+typedef struct ossl_qrx_pkt_st OSSL_QRX_PKT;
+typedef struct ossl_qtx_pkt_st OSSL_QTX_PKT;
+typedef struct quic_tick_result_st QUIC_TICK_RESULT;
+typedef struct quic_srtm_st QUIC_SRTM;
+typedef struct quic_lcidm_st QUIC_LCIDM;
+typedef struct quic_urxe_st QUIC_URXE;
+typedef struct quic_engine_st QUIC_ENGINE;
+
+# endif
+
+#endif

+ 185 - 0
libs/openssl/include/internal/quic_rcidm.h

@@ -0,0 +1,185 @@
+/*
+* 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
+*/
+
+#ifndef OSSL_INTERNAL_QUIC_RCIDM_H
+# define OSSL_INTERNAL_QUIC_RCIDM_H
+# pragma once
+
+# include "internal/e_os.h"
+# include "internal/time.h"
+# include "internal/quic_types.h"
+# include "internal/quic_wire.h"
+
+# ifndef OPENSSL_NO_QUIC
+
+/*
+ * QUIC Remote Connection ID Manager
+ * =================================
+ *
+ * This manages connection IDs for the TX side. The RCIDM tracks remote CIDs
+ * (RCIDs) which a peer has issued to us and which we can use as the DCID of
+ * packets we transmit. It is entirely separate from the LCIDM, which handles
+ * routing received packets by their DCIDs.
+ *
+ * RCIDs fall into four categories:
+ *
+ *   1. A client's Initial ODCID                        (0..1)
+ *   2. A peer's Initial SCID                           (1)
+ *   3. A server's Retry SCID                           (0..1)
+ *   4. A CID issued via a NEW_CONNECTION_ID frame      (n)
+ *
+ * Unlike a LCIDM, which is per port, a RCIDM is per connection, as there is no
+ * need for routing of outgoing packets.
+ */
+typedef struct quic_rcidm_st QUIC_RCIDM;
+
+/*
+ * Creates a new RCIDM. Returns NULL on failure.
+ *
+ * For a client, initial_odcid is the client's Initial ODCID.
+ * For a server, initial_odcid is NULL.
+ */
+QUIC_RCIDM *ossl_quic_rcidm_new(const QUIC_CONN_ID *initial_odcid);
+
+/* Frees a RCIDM. */
+void ossl_quic_rcidm_free(QUIC_RCIDM *rcidm);
+
+/*
+ * CID Events
+ * ==========
+ */
+
+/*
+ * To be called by a client when a server responds to the first Initial packet
+ * sent with its own Initial packet with its own SCID; or to be called by a
+ * server when we first get an Initial packet from a client with the client's
+ * supplied SCID. The added RCID implicitly has a sequence number of 0.
+ *
+ * We immediately switch to using this SCID as our preferred RCID. This SCID
+ * must be enrolled using this function. May only be called once.
+ */
+int ossl_quic_rcidm_add_from_initial(QUIC_RCIDM *rcidm,
+                                     const QUIC_CONN_ID *rcid);
+
+/*
+ * To be called by a client when a server responds to the first Initial packet
+ * sent with a Retry packet with its own SCID (the "Retry ODCID"). We
+ * immediately switch to using this SCID as our preferred RCID when conducting
+ * the retry. This SCID must be enrolled using this function. May only be called
+ * once. The added RCID has no sequence number associated with it as it is
+ * essentially a new ODCID (hereafter a Retry ODCID).
+ *
+ * Not for server use.
+ */
+int ossl_quic_rcidm_add_from_server_retry(QUIC_RCIDM *rcidm,
+                                          const QUIC_CONN_ID *retry_odcid);
+
+/*
+ * Processes an incoming NEW_CONN_ID frame, recording the new CID as a potential
+ * RCID. The RCIDM retirement mechanism is ratcheted according to the
+ * ncid->retire_prior_to field. The stateless_reset field is ignored; the caller
+ * is responsible for handling it separately.
+ */
+int ossl_quic_rcidm_add_from_ncid(QUIC_RCIDM *rcidm,
+                                  const OSSL_QUIC_FRAME_NEW_CONN_ID *ncid);
+
+/*
+ * Other Events
+ * ============
+ */
+
+/*
+ * Notifies the RCIDM that the handshake for a connection is complete.
+ * Should only be called once; further calls are ignored.
+ *
+ * This may influence the RCIDM's RCID change policy.
+ */
+void ossl_quic_rcidm_on_handshake_complete(QUIC_RCIDM *rcidm);
+
+/*
+ * Notifies the RCIDM that one or more packets have been sent.
+ *
+ * This may influence the RCIDM's RCID change policy.
+ */
+void ossl_quic_rcidm_on_packet_sent(QUIC_RCIDM *rcidm, uint64_t num_packets);
+
+/*
+ * Manually request switching to a new RCID as soon as possible.
+ */
+void ossl_quic_rcidm_request_roll(QUIC_RCIDM *rcidm);
+
+/*
+ * Queries
+ * =======
+ */
+
+/*
+ * The RCIDM decides when it will never use a given RCID again. When it does
+ * this, it outputs the sequence number of that RCID using this function, which
+ * pops from a logical queue of retired RCIDs. The caller is responsible
+ * for polling this function and generating Retire CID frames from the result.
+ *
+ * If nothing needs doing and the queue is empty, this function returns 0. If
+ * there is an RCID which needs retiring, the sequence number of that RCID is
+ * written to *seq_num (if seq_num is non-NULL) and this function returns 1. The
+ * queue entry is popped (and the caller is thus assumed to have taken
+ * responsibility for transmitting the necessary Retire CID frame).
+ *
+ * Note that the caller should not transmit a Retire CID frame immediately as
+ * packets using the RCID may still be in flight. The caller must determine an
+ * appropriate delay using knowledge of network conditions (RTT, etc.) which is
+ * outside the scope of the RCIDM. The caller is responsible for implementing
+ * this delay based on the last time a packet was transmitted using the RCID
+ * being retired.
+ */
+int ossl_quic_rcidm_pop_retire_seq_num(QUIC_RCIDM *rcid, uint64_t *seq_num);
+
+/*
+ * Like ossl_quic_rcidm_pop_retire_seq_num, but does not pop the item from the
+ * queue. If this call succeeds, the next call to
+ * ossl_quic_rcidm_pop_retire_seq_num is guaranteed to output the same sequence
+ * number.
+ */
+int ossl_quic_rcidm_peek_retire_seq_num(QUIC_RCIDM *rcid, uint64_t *seq_num);
+
+/*
+ * Writes the DCID preferred for a newly transmitted packet at this time to
+ * *tx_dcid. This function should be called to determine what DCID to use when
+ * transmitting a packet to the peer. The RCIDM may implement arbitrary policy
+ * to decide when to change the preferred RCID.
+ *
+ * Returns 1 on success and 0 on failure.
+ */
+int ossl_quic_rcidm_get_preferred_tx_dcid(QUIC_RCIDM *rcidm,
+                                          QUIC_CONN_ID *tx_dcid);
+
+/*
+ * Returns 1 if the value output by ossl_quic_rcidm_get_preferred_tx_dcid() has
+ * changed since the last call to this function with clear set. If clear is set,
+ * clears the changed flag. Returns the old value of the changed flag.
+ */
+int ossl_quic_rcidm_get_preferred_tx_dcid_changed(QUIC_RCIDM *rcidm,
+                                                  int clear);
+
+/*
+ * Returns the number of active numbered RCIDs we have. Note that this includes
+ * RCIDs on the retir*ing* queue accessed via
+ * ossl_quic_rcidm_pop_retire_seq_num() as these are still active until actually
+ * retired.
+ */
+size_t ossl_quic_rcidm_get_num_active(const QUIC_RCIDM *rcidm);
+
+/*
+ * Returns the number of retir*ing* numbered RCIDs we have.
+ */
+size_t ossl_quic_rcidm_get_num_retiring(const QUIC_RCIDM *rcidm);
+
+# endif
+
+#endif

+ 15 - 5
libs/openssl/include/internal/quic_reactor.h

@@ -11,6 +11,7 @@
 
 # include "internal/time.h"
 # include "internal/sockets.h"
+# include "internal/quic_predef.h"
 # include "internal/thread_arch.h"
 # include <openssl/bio.h>
 
@@ -68,13 +69,22 @@
  * adaptation layer on top of our internal asynchronous I/O API as exposed by
  * the reactor interface.
  */
-typedef struct quic_tick_result_st {
+struct quic_tick_result_st {
     char        net_read_desired;
     char        net_write_desired;
     OSSL_TIME   tick_deadline;
-} QUIC_TICK_RESULT;
-
-typedef struct quic_reactor_st {
+};
+
+static ossl_inline ossl_unused void
+ossl_quic_tick_result_merge_into(QUIC_TICK_RESULT *r,
+                                 const QUIC_TICK_RESULT *src)
+{
+    r->net_read_desired  = r->net_read_desired  || src->net_read_desired;
+    r->net_write_desired = r->net_write_desired || src->net_write_desired;
+    r->tick_deadline     = ossl_time_min(r->tick_deadline, src->tick_deadline);
+}
+
+struct quic_reactor_st {
     /*
      * BIO poll descriptors which can be polled. poll_r is a poll descriptor
      * which becomes readable when the QUIC state machine can potentially do
@@ -102,7 +112,7 @@ typedef struct quic_reactor_st {
      */
     unsigned int can_poll_r : 1;
     unsigned int can_poll_w : 1;
-} QUIC_REACTOR;
+};
 
 void ossl_quic_reactor_init(QUIC_REACTOR *rtor,
                             void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg,

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