diff --git a/ChangeLog b/ChangeLog index d025a9edc..f86a6d3f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,35 +1,65 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [24.6.1.604] - 2024-06-29 + +### Changes + + * Upgrade dependencies: OpenSSL 3.3.1 + * Clarify .ppk file prompt: add (.ppk) +https://forum.farmanager.com/viewtopic.php?p=177884#p177884 + +### Fixes + + * gh-485 Can not create a remote folder +https://github.com/michaellukashov/Far-NetBox/issues/485 + + +## [24.6.0.603] - 2024-06-20 + +### Changes + + * Upgrade dependencies: OpenSSL 3.2.2 + +### Fixes + +Thanks to ssvine https://github.com/ssvine + * gh-484 Fix writing code page to database + * gh-483 Fix unexpected session closure when clicking Abort + * gh-482 Fix FTP codepage support + + ## [24.5.0.602] - 2024-05-05 ### Changes -* gh-467 Update PuTTY to 0.81 -* gh-461 Tell AppVeyour to keep build artifacts + + * gh-467 Update PuTTY to 0.81 + * gh-461 Tell AppVeyour to keep build artifacts ### Fixes Thanks to ssvine https://github.com/ssvine -* gh-469 Fix log time format -* gh-468 Fix MFC termination -* gh-466 Fix Charset encoding for filenames -* gh-465 Fix dialog message -* gh-463 Fix freeze on exit -* gh-462 Fix possible crashes on lost connections while modal dialog is shown -* gh-459 Fix ssh crash on reconnect -* gh-458 Fix broken terminal output -* gh-457 Fix properties implementation + * gh-469 Fix log time format + * gh-468 Fix MFC termination + * gh-466 Fix Charset encoding for filenames + * gh-465 Fix dialog message + * gh-463 Fix freeze on exit + * gh-462 Fix possible crashes on lost connections while modal dialog is shown + * gh-459 Fix ssh crash on reconnect + * gh-458 Fix broken terminal output + * gh-457 Fix properties implementation + ## [24.4.1.601] - 2024-04-10 ### Fixes Thanks to ssvine https://github.com/ssvine -* gh-455 Fix webdav prefix -* gh-454 Fix WebDAV preserve time -* gh-453 Fix hotkey problems -* gh-452 Fix editor not taking transfer settings into account -* gh-451 Fix openssl compilation flags to prevent DLL pinning + * gh-455 Fix webdav prefix + * gh-454 Fix WebDAV preserve time + * gh-453 Fix hotkey problems + * gh-452 Fix editor not taking transfer settings into account + * gh-451 Fix openssl compilation flags to prevent DLL pinning ## [24.4.0.600] - 2024-04-03 @@ -40,14 +70,14 @@ Thanks to ssvine https://github.com/ssvine https://github.com/FarGroup/FarManager/issues/816 Thanks to ssvine https://github.com/ssvine -* gh-449 Fix SFTP crash when resuming copy from local to remote -* gh-447 Fix crash when trying to copy parent directory entry -* gh-446 Fix Alt-F12 history navigation -* gh-445 Relax file naming restrictions -* gh-444 Fix regression: closing FTP does not completely clear the session -* gh-443 Several crashes -* gh-442 Fix several crashes -* gh-441 Fix WebDAV and S3 crash under some conditions + * gh-449 Fix SFTP crash when resuming copy from local to remote + * gh-447 Fix crash when trying to copy parent directory entry + * gh-446 Fix Alt-F12 history navigation + * gh-445 Relax file naming restrictions + * gh-444 Fix regression: closing FTP does not completely clear the session + * gh-443 Several crashes + * gh-442 Fix several crashes + * gh-441 Fix WebDAV and S3 crash under some conditions ## [24.3.1.599] - 2024-03-22 diff --git a/libs/openssl-3/crypto/aes/aes_x86core.c b/libs/openssl-3/crypto/aes/aes_x86core.c index 8e54e80a6..3e5b24ed1 100644 --- a/libs/openssl-3/crypto/aes/aes_x86core.c +++ b/libs/openssl-3/crypto/aes/aes_x86core.c @@ -81,13 +81,10 @@ static void prefetch256(const void *table) #define GETU32(p) (*((u32*)(p))) #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) -typedef unsigned __int64 u64; #define U64(C) C##UI64 #elif defined(__arch64__) -typedef unsigned long u64; #define U64(C) C##UL #else -typedef unsigned long long u64; #define U64(C) C##ULL #endif diff --git a/libs/openssl-3/crypto/arm_arch.h b/libs/openssl-3/crypto/arm_arch.h index 83acbe012..7ac978fec 100644 --- a/libs/openssl-3/crypto/arm_arch.h +++ b/libs/openssl-3/crypto/arm_arch.h @@ -1,5 +1,5 @@ /* - * Copyright 2011-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -88,6 +88,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized; # define ARMV8_SVE (1<<13) # define ARMV8_SVE2 (1<<14) # define ARMV8_HAVE_SHA3_AND_WORTH_USING (1<<15) +# define ARMV8_UNROLL12_EOR3 (1<<16) /* * MIDR_EL1 system register @@ -102,6 +103,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized; # define ARM_CPU_IMP_ARM 0x41 # define HISI_CPU_IMP 0x48 # define ARM_CPU_IMP_APPLE 0x61 +# define ARM_CPU_IMP_MICROSOFT 0x6D # define ARM_CPU_PART_CORTEX_A72 0xD08 # define ARM_CPU_PART_N1 0xD0C @@ -123,6 +125,8 @@ extern unsigned int OPENSSL_armv8_rsa_neonized; # define APPLE_CPU_PART_M2_BLIZZARD_MAX 0x038 # define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039 +# define MICROSOFT_CPU_PART_COBALT_100 0xD49 + # define MIDR_PARTNUM_SHIFT 4 # define MIDR_PARTNUM_MASK (0xfffU << MIDR_PARTNUM_SHIFT) # define MIDR_PARTNUM(midr) \ diff --git a/libs/openssl-3/crypto/armcap.c b/libs/openssl-3/crypto/armcap.c index 3b1447456..781503eda 100644 --- a/libs/openssl-3/crypto/armcap.c +++ b/libs/openssl-3/crypto/armcap.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -298,7 +298,8 @@ void OPENSSL_cpuid_setup(void) size_t len = sizeof(uarch); if ((sysctlbyname("machdep.cpu.brand_string", uarch, &len, NULL, 0) == 0) && ((strncmp(uarch, "Apple M1", 8) == 0) || - (strncmp(uarch, "Apple M2", 8) == 0))) { + (strncmp(uarch, "Apple M2", 8) == 0) || + (strncmp(uarch, "Apple M3", 8) == 0))) { OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3; OPENSSL_armcap_P |= ARMV8_HAVE_SHA3_AND_WORTH_USING; } @@ -417,9 +418,14 @@ void OPENSSL_cpuid_setup(void) } if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N2) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_COBALT_100) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)) && (OPENSSL_armcap_P & ARMV8_SHA3)) OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3; + if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)) && + (OPENSSL_armcap_P & ARMV8_SHA3)) + OPENSSL_armcap_P |= ARMV8_UNROLL12_EOR3; if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) || diff --git a/libs/openssl-3/crypto/asn1/a_time.c b/libs/openssl-3/crypto/asn1/a_time.c index bcf313536..96ee63d31 100644 --- a/libs/openssl-3/crypto/asn1/a_time.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/asn1/asn1_err.c b/libs/openssl-3/crypto/asn1/asn1_err.c index a7b32e3a6..f52584244 100644 --- a/libs/openssl-3/crypto/asn1/asn1_err.c +++ b/libs/openssl-3/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), diff --git a/libs/openssl-3/crypto/asn1/tasn_dec.c b/libs/openssl-3/crypto/asn1/tasn_dec.c index 5c65d542c..c4f9d6151 100644 --- a/libs/openssl-3/crypto/asn1/tasn_dec.c +++ b/libs/openssl-3/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); diff --git a/libs/openssl-3/crypto/bio/bio_dump.c b/libs/openssl-3/crypto/bio/bio_dump.c index c453da626..40c18410e 100644 --- a/libs/openssl-3/crypto/bio/bio_dump.c +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/crypto/bio/bio_lib.c b/libs/openssl-3/crypto/bio/bio_lib.c index b3605b844..272189a9a 100644 --- a/libs/openssl-3/crypto/bio/bio_lib.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/bio/bio_meth.c b/libs/openssl-3/crypto/bio/bio_meth.c index 30b1db5aa..f6fdcb935 100644 --- a/libs/openssl-3/crypto/bio/bio_meth.c +++ b/libs/openssl-3/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; } diff --git a/libs/openssl-3/crypto/bio/bio_sock.c b/libs/openssl-3/crypto/bio/bio_sock.c index 676707ad0..ea28fd282 100644 --- a/libs/openssl-3/crypto/bio/bio_sock.c +++ b/libs/openssl-3/crypto/bio/bio_sock.c @@ -26,9 +26,6 @@ static int wsa_init_done = 0; # if defined __TANDEM # include # include /* select */ -# if defined(OPENSSL_TANDEM_FLOSS) -# include -# endif # elif defined _WIN32 # include /* for type fd_set */ # else diff --git a/libs/openssl-3/crypto/bio/bss_dgram.c b/libs/openssl-3/crypto/bio/bss_dgram.c index 69f3b4860..f6d688b35 100644 --- a/libs/openssl-3/crypto/bio/bss_dgram.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/bn/bn_const.c b/libs/openssl-3/crypto/bn/bn_const.c index 4224d88e8..190a36391 100644 --- a/libs/openssl-3/crypto/bn/bn_const.c +++ b/libs/openssl-3/crypto/bn/bn_const.c @@ -9,7 +9,6 @@ #include #include "crypto/bn_dh.h" -#include "bn_local.h" // WINSCP #define COPY_BN(dst, src) (dst != NULL) ? BN_copy(dst, &src) : BN_dup(&src) diff --git a/libs/openssl-3/crypto/bn/bn_gcd.c b/libs/openssl-3/crypto/bn/bn_gcd.c index 7303d3b95..2cd8ee35e 100644 --- a/libs/openssl-3/crypto/bn/bn_gcd.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/bn/bn_mod.c b/libs/openssl-3/crypto/bn/bn_mod.c index ce58d5501..d7c2f4bd5 100644 --- a/libs/openssl-3/crypto/bn/bn_mod.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/buildinf.h b/libs/openssl-3/crypto/buildinf.h index 366ddeb0c..4fe3d07af 100644 --- a/libs/openssl-3/crypto/buildinf.h +++ b/libs/openssl-3/crypto/buildinf.h @@ -10,13 +10,15 @@ * https://www.openssl.org/source/license.html */ +#define DATE "built on: Sat Jun 29 09:04:57 2024 UTC" #if defined(_WIN64) || defined(OPENSSL_SYS_WIN64) #define PLATFORM "platform: VC-WIN64A" -#define DATE "built on: Fri Feb 2 19:14:22 2024 UTC" #endif #if defined(_WIN32) || defined(OPENSSL_SYS_WIN32) #define PLATFORM "platform: VC-WIN32" -#define DATE "built on: Fri Feb 2 20:36:20 2024 UTC" +#endif +#if defined(_M_ARM64) +#define PLATFORM "platform: VC-WIN64-ARM" #endif /* diff --git a/libs/openssl-3/crypto/chacha/chacha_enc.c b/libs/openssl-3/crypto/chacha/chacha_enc.c index f8f183590..f6fbc1198 100644 --- a/libs/openssl-3/crypto/chacha/chacha_enc.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/chacha/chacha_riscv.c b/libs/openssl-3/crypto/chacha/chacha_riscv.c new file mode 100644 index 000000000..06e0400ba --- /dev/null +++ b/libs/openssl-3/crypto/chacha/chacha_riscv.c @@ -0,0 +1,56 @@ +/* + * This file is dual-licensed, meaning that you can use it under your + * choice of either of the following two licenses: + * + * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * or + * + * Copyright (c) 2023, Jerry Shih + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "crypto/chacha.h" +#include "crypto/riscv_arch.h" + +void ChaCha20_ctr32_zbb_zvkb(unsigned char *out, const unsigned char *inp, + size_t len, const unsigned int key[8], + const unsigned int counter[4]); + +void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len, + const unsigned int key[8], const unsigned int counter[4]) +{ + if (len > CHACHA_BLK_SIZE && RISCV_HAS_ZVKB() && RISCV_HAS_ZBB() && + riscv_vlen() >= 128) { + ChaCha20_ctr32_zbb_zvkb(out, inp, len, key, counter); + } else { + ChaCha20_ctr32_c(out, inp, len, key, counter); + } +} diff --git a/libs/openssl-3/crypto/cmac/cmac.c b/libs/openssl-3/crypto/cmac/cmac.c index 50c8511ba..2012774f8 100644 --- a/libs/openssl-3/crypto/cmac/cmac.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/cmp/cmp_asn.c b/libs/openssl-3/crypto/cmp/cmp_asn.c index 0133dc5f8..3285cbf42 100644 --- a/libs/openssl-3/crypto/cmp/cmp_asn.c +++ b/libs/openssl-3/crypto/cmp/cmp_asn.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -58,11 +58,7 @@ IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT) ASN1_SEQUENCE(OSSL_CMP_ERRORMSGCONTENT) = { ASN1_SIMPLE(OSSL_CMP_ERRORMSGCONTENT, pKIStatusInfo, OSSL_CMP_PKISI), ASN1_OPT(OSSL_CMP_ERRORMSGCONTENT, errorCode, ASN1_INTEGER), - /* - * OSSL_CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING - * so it is used directly - * - */ + /* OSSL_CMP_PKIFREETEXT is a ASN1_UTF8STRING sequence, so used directly */ ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ERRORMSGCONTENT, errorDetails, ASN1_UTF8STRING) } ASN1_SEQUENCE_END(OSSL_CMP_ERRORMSGCONTENT) @@ -121,6 +117,9 @@ ASN1_ADB(OSSL_CMP_ITAV) = { ADB_ENTRY(NID_id_it_rootCaKeyUpdate, ASN1_OPT(OSSL_CMP_ITAV, infoValue.rootCaKeyUpdate, OSSL_CMP_ROOTCAKEYUPDATE)), + ADB_ENTRY(NID_id_it_certProfile, + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.certProfile, + ASN1_UTF8STRING)), } ASN1_ADB_END(OSSL_CMP_ITAV, 0, infoType, 0, &infotypeandvalue_default_tt, NULL); @@ -190,13 +189,40 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, return 1; err: - if (created != 0) { + if (created) { sk_OSSL_CMP_ITAV_free(*itav_sk_p); *itav_sk_p = NULL; } return 0; } +OSSL_CMP_ITAV +*OSSL_CMP_ITAV_new0_certProfile(STACK_OF(ASN1_UTF8STRING) *certProfile) +{ + OSSL_CMP_ITAV *itav; + + if ((itav = OSSL_CMP_ITAV_new()) == NULL) + return NULL; + itav->infoType = OBJ_nid2obj(NID_id_it_certProfile); + itav->infoValue.certProfile = certProfile; + return itav; +} + +int OSSL_CMP_ITAV_get0_certProfile(const OSSL_CMP_ITAV *itav, + STACK_OF(ASN1_UTF8STRING) **out) +{ + if (itav == NULL || out == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (OBJ_obj2nid(itav->infoType) != NID_id_it_certProfile) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + *out = itav->infoValue.certProfile; + return 1; +} + OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts) { OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new(); @@ -261,23 +287,30 @@ OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew, const X509 *oldWithNew) { OSSL_CMP_ITAV *itav; - OSSL_CMP_ROOTCAKEYUPDATE *upd = OSSL_CMP_ROOTCAKEYUPDATE_new(); + OSSL_CMP_ROOTCAKEYUPDATE *upd = NULL; + + if (newWithNew != NULL) { + upd = OSSL_CMP_ROOTCAKEYUPDATE_new(); + if (upd == NULL) + return NULL; + + if ((upd->newWithNew = X509_dup(newWithNew)) == NULL) + goto err; + if (newWithOld != NULL + && (upd->newWithOld = X509_dup(newWithOld)) == NULL) + goto err; + if (oldWithNew != NULL + && (upd->oldWithNew = X509_dup(oldWithNew)) == NULL) + goto err; + } - if (upd == NULL) - return NULL; - if (newWithNew != NULL && (upd->newWithNew = X509_dup(newWithNew)) == NULL) - goto err; - if (newWithOld != NULL && (upd->newWithOld = X509_dup(newWithOld)) == NULL) - goto err; - if (oldWithNew != NULL && (upd->oldWithNew = X509_dup(oldWithNew)) == NULL) - goto err; if ((itav = OSSL_CMP_ITAV_new()) == NULL) goto err; itav->infoType = OBJ_nid2obj(NID_id_it_rootCaKeyUpdate); itav->infoValue.rootCaKeyUpdate = upd; return itav; - err: + err: OSSL_CMP_ROOTCAKEYUPDATE_free(upd); return NULL; } @@ -298,11 +331,11 @@ int OSSL_CMP_ITAV_get0_rootCaKeyUpdate(const OSSL_CMP_ITAV *itav, return 0; } upd = itav->infoValue.rootCaKeyUpdate; - *newWithNew = upd->newWithNew; + *newWithNew = upd != NULL ? upd->newWithNew : NULL; if (newWithOld != NULL) - *newWithOld = upd->newWithOld; + *newWithOld = upd != NULL ? upd->newWithOld : NULL; if (oldWithNew != NULL) - *oldWithNew = upd->oldWithNew; + *oldWithNew = upd != NULL ? upd->oldWithNew : NULL; return 1; } @@ -327,7 +360,7 @@ int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a) } static int ossl_cmp_msg_cb(int operation, ASN1_VALUE **pval, - const ASN1_ITEM *it, void *exarg) + ossl_unused const ASN1_ITEM *it, void *exarg) { OSSL_CMP_MSG *msg = (OSSL_CMP_MSG *)*pval; @@ -417,14 +450,9 @@ ASN1_ITEM_TEMPLATE_END(OSSL_CMP_PKISTATUS) ASN1_SEQUENCE(OSSL_CMP_PKISI) = { ASN1_SIMPLE(OSSL_CMP_PKISI, status, OSSL_CMP_PKISTATUS), - /* - * CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING - * so it is used directly - */ + /* OSSL_CMP_PKIFREETEXT is a ASN1_UTF8STRING sequence, so used directly */ ASN1_SEQUENCE_OF_OPT(OSSL_CMP_PKISI, statusString, ASN1_UTF8STRING), - /* - * OSSL_CMP_PKIFAILUREINFO is effectively ASN1_BIT_STRING so used directly - */ + /* OSSL_CMP_PKIFAILUREINFO is effectively ASN1_BIT_STRING, used directly */ ASN1_OPT(OSSL_CMP_PKISI, failInfo, ASN1_BIT_STRING) } ASN1_SEQUENCE_END(OSSL_CMP_PKISI) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_PKISI) @@ -541,10 +569,7 @@ ASN1_SEQUENCE(OSSL_CMP_PKIHEADER) = { ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, transactionID, ASN1_OCTET_STRING, 4), ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, senderNonce, ASN1_OCTET_STRING, 5), ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, recipNonce, ASN1_OCTET_STRING, 6), - /* - * OSSL_CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING - * so it is used directly - */ + /* OSSL_CMP_PKIFREETEXT is a ASN1_UTF8STRING sequence, so used directly */ ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, freeText, ASN1_UTF8STRING, 7), ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, generalInfo, OSSL_CMP_ITAV, 8) diff --git a/libs/openssl-3/crypto/cmp/cmp_client.c b/libs/openssl-3/crypto/cmp/cmp_client.c index b5b0557b0..d588bb358 100644 --- a/libs/openssl-3/crypto/cmp/cmp_client.c +++ b/libs/openssl-3/crypto/cmp/cmp_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -113,6 +113,23 @@ static int save_statusInfo(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si) return 1; } +static int is_crep_with_waiting(const OSSL_CMP_MSG *resp, int rid) +{ + OSSL_CMP_CERTREPMESSAGE *crepmsg; + OSSL_CMP_CERTRESPONSE *crep; + int bt = OSSL_CMP_MSG_get_bodytype(resp); + + if (!IS_CREP(bt)) + return 0; + + crepmsg = resp->body->value.ip; /* same for cp and kup */ + crep = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, rid); + + return (crep != NULL + && ossl_cmp_pkisi_get_status(crep->status) + == OSSL_CMP_PKISTATUS_waiting); +} + /*- * Perform the generic aspects of sending a request and receiving a response. * Returns 1 on success and provides the received PKIMESSAGE in *rep. @@ -160,7 +177,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, /* should print error queue since transfer_cb may call ERR_clear_error() */ OSSL_CMP_CTX_print_errors(ctx); - ossl_cmp_log1(INFO, ctx, "sending %s", req_type_str); + if (ctx->server != NULL) + ossl_cmp_log1(INFO, ctx, "sending %s", req_type_str); *rep = (*transfer_cb)(ctx, req); ctx->msg_timeout = bak_msg_timeout; @@ -180,7 +198,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, * Still we use this preliminary value already for a progress report because * the following msg verification may also produce log entries and may fail. */ - ossl_cmp_log1(INFO, ctx, "received %s", ossl_cmp_bodytype_to_string(bt)); + ossl_cmp_log2(INFO, ctx, "received %s%s", ossl_cmp_bodytype_to_string(bt), + ossl_cmp_is_error_with_waiting(*rep) ? " (waiting)" : ""); /* copy received extraCerts to ctx->extraCertsIn so they can be retrieved */ if (bt != OSSL_CMP_PKIBODY_POLLREP && bt != OSSL_CMP_PKIBODY_PKICONF @@ -191,9 +210,17 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, expected_type)) return 0; + /* + * rep can have the expected response type, which during polling is pollRep. + * When polling, also any other non-error response (the final response) + * is fine here. When not yet polling, delayed delivery may be initiated + * by the server returning an error message with 'waiting' status (or a + * response message of expected type ip/cp/kup with 'waiting' status). + */ if (bt == expected_type - /* as an answer to polling, there could be IP/CP/KUP: */ - || (IS_CREP(bt) && expected_type == OSSL_CMP_PKIBODY_POLLREP)) + || (expected_type == OSSL_CMP_PKIBODY_POLLREP + ? bt != OSSL_CMP_PKIBODY_ERROR + : ossl_cmp_is_error_with_waiting(*rep))) return 1; /* received message type is not one of the expected ones (e.g., error) */ @@ -235,7 +262,7 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, /*- * When a 'waiting' PKIStatus has been received, this function is used to - * poll, which should yield a pollRep or finally a CertRepMessage in ip/cp/kup. + * poll, which should yield a pollRep or the final response. * On receiving a pollRep, which includes a checkAfter value, it return this * value if sleep == 0, else it sleeps as long as indicated and retries. * @@ -246,7 +273,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, * Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value. * Returns 1 on success and provides the received PKIMESSAGE in *rep. * In this case the caller is responsible for freeing *rep. - * Returns 0 on error (which includes the case that timeout has been reached). + * Returns 0 on error (which includes the cases that timeout has been reached + * or a response with 'waiting' status has been received). */ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid, OSSL_CMP_MSG **rep, int *checkAfter) @@ -312,7 +340,7 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid, str, check_after); if (ctx->total_timeout != 0) { /* timeout is not infinite */ - const int exp = 5; /* expected max time per msg round trip */ + const int exp = OSSL_CMP_EXPECTED_RESP_TIME; int64_t time_left = (int64_t)(ctx->end_time - exp - time(NULL)); if (time_left <= 0) { @@ -335,9 +363,19 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid, *checkAfter = (int)check_after; return -1; /* exits the loop */ } + } else if (is_crep_with_waiting(prep, rid) + || ossl_cmp_is_error_with_waiting(prep)) { + /* received status must not be 'waiting' */ + (void)ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection, + OSSL_CMP_CTX_FAILINFO_badRequest, + "polling already started", + 0 /* errorCode */, NULL); + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKISTATUS); + goto err; } else { - ossl_cmp_info(ctx, "received ip/cp/kup after polling"); - /* any other body type has been rejected by send_receive_check() */ + ossl_cmp_info(ctx, "received final response after polling"); + if (!ossl_cmp_ctx_set1_first_senderNonce(ctx, NULL)) + return 0; break; } } @@ -349,11 +387,63 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid, return 1; err: + (void)ossl_cmp_ctx_set1_first_senderNonce(ctx, NULL); OSSL_CMP_MSG_free(preq); OSSL_CMP_MSG_free(prep); return 0; } +static int save_senderNonce_if_waiting(OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *rep, int rid) +{ + /* + * Lightweight CMP Profile section 4.4 states: the senderNonce of the + * preceding request message because this value will be needed for checking + * the recipNonce of the final response to be received after polling. + */ + if ((is_crep_with_waiting(rep, rid) + || ossl_cmp_is_error_with_waiting(rep)) + && !ossl_cmp_ctx_set1_first_senderNonce(ctx, ctx->senderNonce)) + return 0; + + return 1; +} + +/* + * Send request and get response possibly with polling initiated by error msg. + * Polling for ip/cp/kup/ with 'waiting' status is handled by cert_response(). + */ +static int send_receive_also_delayed(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, + OSSL_CMP_MSG **rep, int expected_type) +{ + + if (!send_receive_check(ctx, req, rep, expected_type)) + return 0; + + if (ossl_cmp_is_error_with_waiting(*rep)) { + if (!save_senderNonce_if_waiting(ctx, *rep, OSSL_CMP_CERTREQID_NONE)) + return 0; + /* not modifying ctx->status during certConf and error exchanges */ + if (expected_type != OSSL_CMP_PKIBODY_PKICONF + && !save_statusInfo(ctx, (*rep)->body->value.error->pKIStatusInfo)) + return 0; + + OSSL_CMP_MSG_free(*rep); + *rep = NULL; + + if (poll_for_response(ctx, 1 /* can sleep */, OSSL_CMP_CERTREQID_NONE, + rep, NULL /* checkAfter */) <= 0) { + ERR_raise(ERR_LIB_CMP, CMP_R_POLLING_FAILED); + return 0; + } + } + if (OSSL_CMP_MSG_get_bodytype(*rep) != expected_type) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + return 0; + } + + return 1; +} /* * Send certConf for IR, CR or KUR sequences and check response, * not modifying ctx->status during the certConf exchange @@ -370,7 +460,8 @@ int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int certReqId, if (certConf == NULL) goto err; - res = send_receive_check(ctx, certConf, &PKIconf, OSSL_CMP_PKIBODY_PKICONF); + res = send_receive_also_delayed(ctx, certConf, &PKIconf, + OSSL_CMP_PKIBODY_PKICONF); err: OSSL_CMP_MSG_free(certConf); @@ -394,7 +485,8 @@ int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info, if ((error = ossl_cmp_error_new(ctx, si, errorCode, details, 0)) == NULL) goto err; - res = send_receive_check(ctx, error, &PKIconf, OSSL_CMP_PKIBODY_PKICONF); + res = send_receive_also_delayed(ctx, error, + &PKIconf, OSSL_CMP_PKIBODY_PKICONF); err: OSSL_CMP_MSG_free(error); @@ -515,7 +607,7 @@ int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, if (X509_verify_cert(csc) <= 0) goto err; - if (!ossl_x509_add_certs_new(&chain, X509_STORE_CTX_get0_chain(csc), + if (!ossl_x509_add_certs_new(&chain, X509_STORE_CTX_get0_chain(csc), X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP | X509_ADD_FLAG_NO_SS)) { sk_X509_free(chain); @@ -564,48 +656,78 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid, EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx); int fail_info = 0; /* no failure */ const char *txt = NULL; - OSSL_CMP_CERTREPMESSAGE *crepmsg; - OSSL_CMP_CERTRESPONSE *crep; + OSSL_CMP_CERTREPMESSAGE *crepmsg = NULL; + OSSL_CMP_CERTRESPONSE *crep = NULL; OSSL_CMP_certConf_cb_t cb; X509 *cert; char *subj = NULL; int ret = 1; + int rcvd_type; + OSSL_CMP_PKISI *si; if (!ossl_assert(ctx != NULL)) return 0; retry: - crepmsg = (*resp)->body->value.ip; /* same for cp and kup */ - if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1) { - ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED); - return 0; - } - crep = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, rid); - if (crep == NULL) - return 0; - if (!save_statusInfo(ctx, crep->status)) - return 0; - if (rid == OSSL_CMP_CERTREQID_NONE) { /* used for OSSL_CMP_PKIBODY_P10CR */ - rid = ossl_cmp_asn1_get_int(crep->certReqId); - if (rid < OSSL_CMP_CERTREQID_NONE) { - ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); + rcvd_type = OSSL_CMP_MSG_get_bodytype(*resp); + if (IS_CREP(rcvd_type)) { + crepmsg = (*resp)->body->value.ip; /* same for cp and kup */ + if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1) { + ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED); return 0; } + crep = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, rid); + if (crep == NULL) + return 0; + si = crep->status; + + if (rid == OSSL_CMP_CERTREQID_NONE) { + /* for OSSL_CMP_PKIBODY_P10CR learn CertReqId from response */ + rid = ossl_cmp_asn1_get_int(crep->certReqId); + if (rid < OSSL_CMP_CERTREQID_NONE) { + ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); + return 0; + } + } + } else if (rcvd_type == OSSL_CMP_PKIBODY_ERROR) { + si = (*resp)->body->value.error->pKIStatusInfo; + } else { + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + return 0; } - if (ossl_cmp_pkisi_get_status(crep->status) == OSSL_CMP_PKISTATUS_waiting) { + if (!save_statusInfo(ctx, si)) + return 0; + + if (ossl_cmp_pkisi_get_status(si) == OSSL_CMP_PKISTATUS_waiting) { + /* + * Here we allow both and error message with waiting indication + * as well as a certificate response with waiting indication, where + * its flavor (ip, cp, or kup) may not strictly match ir/cr/p10cr/kur. + */ OSSL_CMP_MSG_free(*resp); *resp = NULL; if ((ret = poll_for_response(ctx, sleep, rid, resp, checkAfter)) != 0) { if (ret == -1) /* at this point implies sleep == 0 */ return ret; /* waiting */ - goto retry; /* got ip/cp/kup, which may still indicate 'waiting' */ + goto retry; /* got some response other than pollRep */ } else { ERR_raise(ERR_LIB_CMP, CMP_R_POLLING_FAILED); return 0; } } + /* at this point, we have received ip/cp/kup/error without waiting */ + if (rcvd_type == OSSL_CMP_PKIBODY_ERROR) { + ERR_raise(ERR_LIB_CMP, CMP_R_RECEIVED_ERROR); + return 0; + } + /* here we are strict on the flavor of ip/cp/kup: must match request */ + if (rcvd_type != expected_type) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + return 0; + } + cert = get1_cert_status(ctx, (*resp)->body->type, crep); if (cert == NULL) { ERR_add_error_data(1, "; cannot extract certificate from response"); @@ -618,7 +740,7 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid, * if the CMP server returned certificates in the caPubs field, copy them * to the context so that they can be retrieved if necessary */ - if (crepmsg->caPubs != NULL + if (crepmsg != NULL && crepmsg->caPubs != NULL && !ossl_cmp_ctx_set1_caPubs(ctx, crepmsg->caPubs)) return 0; @@ -709,6 +831,9 @@ int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, if (ctx->status != OSSL_CMP_PKISTATUS_waiting) { /* not polling already */ if (!initial_certreq(ctx, req_type, crm, &rep, rep_type)) goto err; + + if (!save_senderNonce_if_waiting(ctx, rep, rid)) + return 0; } else { if (req_type < 0) return ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection, @@ -750,6 +875,9 @@ X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type, if (!initial_certreq(ctx, req_type, crm, &rep, rep_type)) goto err; + if (!save_senderNonce_if_waiting(ctx, rep, rid)) + return 0; + if (cert_response(ctx, 1 /* sleep */, rid, &rep, NULL, req_type, rep_type) <= 0) goto err; @@ -787,7 +915,7 @@ int OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx) goto end; ctx->status = OSSL_CMP_PKISTATUS_trans; - if (!send_receive_check(ctx, rr, &rp, OSSL_CMP_PKIBODY_RP)) + if (!send_receive_also_delayed(ctx, rr, &rp, OSSL_CMP_PKIBODY_RP)) goto end; rrep = rp->body->value.rp; @@ -908,7 +1036,7 @@ STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx) goto err; ctx->status = OSSL_CMP_PKISTATUS_trans; - if (!send_receive_check(ctx, genm, &genp, OSSL_CMP_PKIBODY_GENP)) + if (!send_receive_also_delayed(ctx, genm, &genp, OSSL_CMP_PKIBODY_GENP)) goto err; ctx->status = OSSL_CMP_PKISTATUS_accepted; diff --git a/libs/openssl-3/crypto/cmp/cmp_ctx.c b/libs/openssl-3/crypto/cmp/cmp_ctx.c index 947d2ceb8..7b78ab160 100644 --- a/libs/openssl-3/crypto/cmp/cmp_ctx.c +++ b/libs/openssl-3/crypto/cmp/cmp_ctx.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -183,6 +183,7 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx) && ossl_cmp_ctx_set1_caPubs(ctx, NULL) && ossl_cmp_ctx_set1_extraCertsIn(ctx, NULL) && ossl_cmp_ctx_set1_validatedSrvCert(ctx, NULL) + && ossl_cmp_ctx_set1_first_senderNonce(ctx, NULL) && OSSL_CMP_CTX_set1_transactionID(ctx, NULL) && OSSL_CMP_CTX_set1_senderNonce(ctx, NULL) && ossl_cmp_ctx_set1_recipNonce(ctx, NULL); @@ -226,6 +227,7 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx) ASN1_OCTET_STRING_free(ctx->transactionID); ASN1_OCTET_STRING_free(ctx->senderNonce); ASN1_OCTET_STRING_free(ctx->recipNonce); + ASN1_OCTET_STRING_free(ctx->first_senderNonce); OSSL_CMP_ITAVs_free(ctx->geninfo_ITAVs); OSSL_STACK_OF_X509_free(ctx->extraCertsOut); @@ -534,6 +536,8 @@ int OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx) return 1; } +DEFINE_OSSL_CMP_CTX_get0(geninfo_ITAVs, STACK_OF(OSSL_CMP_ITAV)) + /* Add an itav for the body of outgoing general messages */ int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav) { @@ -812,6 +816,9 @@ DEFINE_set1_ASN1_OCTET_STRING(ossl_cmp_ctx, recipNonce) /* Stores the given nonce as the last senderNonce sent out */ DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, senderNonce) +/* store the first req sender nonce for verifying delayed delivery */ +DEFINE_set1_ASN1_OCTET_STRING(ossl_cmp_ctx, first_senderNonce) + /* Set the proxy server to use for HTTP(S) connections */ DEFINE_OSSL_CMP_CTX_set1(proxy, char) @@ -908,6 +915,9 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) case OSSL_CMP_OPT_UNPROTECTED_ERRORS: ctx->unprotectedErrors = val; break; + case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS: + ctx->noCacheExtraCerts = val; + break; case OSSL_CMP_OPT_VALIDITY_DAYS: ctx->days = val; break; @@ -993,6 +1003,8 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt) return ctx->unprotectedSend; case OSSL_CMP_OPT_UNPROTECTED_ERRORS: return ctx->unprotectedErrors; + case OSSL_CMP_OPT_NO_CACHE_EXTRACERTS: + return ctx->noCacheExtraCerts; case OSSL_CMP_OPT_VALIDITY_DAYS: return ctx->days; case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT: diff --git a/libs/openssl-3/crypto/cmp/cmp_err.c b/libs/openssl-3/crypto/cmp/cmp_err.c index 3853e5260..56ac3691d 100644 --- a/libs/openssl-3/crypto/cmp/cmp_err.c +++ b/libs/openssl-3/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"}, diff --git a/libs/openssl-3/crypto/cmp/cmp_genm.c b/libs/openssl-3/crypto/cmp/cmp_genm.c index dad6ef118..5986036f5 100644 --- a/libs/openssl-3/crypto/cmp/cmp_genm.c +++ b/libs/openssl-3/crypto/cmp/cmp_genm.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright Siemens AG 2022 * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -307,9 +307,11 @@ int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, if (!OSSL_CMP_ITAV_get0_rootCaKeyUpdate(itav, newWithNew, &my_newWithOld, &my_oldWithNew)) goto end; - - if (*newWithNew == NULL) /* no root CA cert update available */ + /* no root CA cert update available */ + if (*newWithNew == NULL) { + res = 1; goto end; + } if ((oldWithOld_copy = X509_dup(oldWithOld)) == NULL && oldWithOld != NULL) goto end; if (!verify_ss_cert_trans(ctx, oldWithOld_copy, my_newWithOld, diff --git a/libs/openssl-3/crypto/cmp/cmp_hdr.c b/libs/openssl-3/crypto/cmp/cmp_hdr.c index 5fabf1aa3..4358b3887 100644 --- a/libs/openssl-3/crypto/cmp/cmp_hdr.c +++ b/libs/openssl-3/crypto/cmp/cmp_hdr.c @@ -72,6 +72,16 @@ ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr) return hdr->recipNonce; } +STACK_OF(OSSL_CMP_ITAV) + *OSSL_CMP_HDR_get0_geninfo_ITAVs(const OSSL_CMP_PKIHEADER *hdr) +{ + if (hdr == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return hdr->generalInfo; +} + /* a NULL-DN as an empty sequence of RDNs */ int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name) { diff --git a/libs/openssl-3/crypto/cmp/cmp_local.h b/libs/openssl-3/crypto/cmp/cmp_local.h index 29aa84cd2..89f05d753 100644 --- a/libs/openssl-3/crypto/cmp/cmp_local.h +++ b/libs/openssl-3/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, diff --git a/libs/openssl-3/crypto/cmp/cmp_msg.c b/libs/openssl-3/crypto/cmp/cmp_msg.c index e00afc809..4ba7b8108 100644 --- a/libs/openssl-3/crypto/cmp/cmp_msg.c +++ b/libs/openssl-3/crypto/cmp/cmp_msg.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -100,6 +100,34 @@ int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG *msg) return msg->body->type; } +X509_PUBKEY *OSSL_CMP_MSG_get0_certreq_publickey(const OSSL_CMP_MSG *msg) +{ + const OSSL_CRMF_MSGS *reqs; + const OSSL_CRMF_MSG *crm; + const OSSL_CRMF_CERTTEMPLATE *tmpl; + X509_PUBKEY *pubkey; + + switch (OSSL_CMP_MSG_get_bodytype(msg)) { + case OSSL_CMP_PKIBODY_IR: + case OSSL_CMP_PKIBODY_CR: + case OSSL_CMP_PKIBODY_KUR: + reqs = msg->body->value.ir; /* value.ir is same for cr and kur */ + if ((crm = sk_OSSL_CRMF_MSG_value(reqs, 0)) == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND); + return NULL; + } + if ((tmpl = OSSL_CRMF_MSG_get0_tmpl(crm)) == NULL + || (pubkey = OSSL_CRMF_CERTTEMPLATE_get0_publicKey(tmpl)) == NULL) { + ERR_raise(ERR_LIB_CMP, CRMF_R_POPO_MISSING_PUBLIC_KEY); + return NULL; + } + return pubkey; + default: + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + return NULL; + } +} + /* Add an extension to the referenced extension stack, which may be NULL */ static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex) { @@ -542,8 +570,7 @@ OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx) } else if (ctx->p10CSR != NULL) { pubkey = X509_REQ_get0_pubkey(ctx->p10CSR); subject = X509_REQ_get_subject_name(ctx->p10CSR); - } - else { + } else { goto err; } @@ -984,8 +1011,7 @@ static int suitable_rid(const ASN1_INTEGER *certReqId, int rid) return 1; trid = ossl_cmp_asn1_get_int(certReqId); - - if (trid == OSSL_CMP_CERTREQID_NONE) { + if (trid <= OSSL_CMP_CERTREQID_INVALID) { ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); return 0; } @@ -1200,3 +1226,13 @@ int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg) { return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg); } + +int ossl_cmp_is_error_with_waiting(const OSSL_CMP_MSG *msg) +{ + if (!ossl_assert(msg != NULL)) + return 0; + + return (OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_ERROR + && ossl_cmp_pkisi_get_status(msg->body->value.error->pKIStatusInfo) + == OSSL_CMP_PKISTATUS_waiting); +} diff --git a/libs/openssl-3/crypto/cmp/cmp_server.c b/libs/openssl-3/crypto/cmp/cmp_server.c index 06ef8fbb6..53c41bc96 100644 --- a/libs/openssl-3/crypto/cmp/cmp_server.c +++ b/libs/openssl-3/crypto/cmp/cmp_server.c @@ -22,9 +22,10 @@ /* the context for the generic CMP server */ struct ossl_cmp_srv_ctx_st { - void *custom_ctx; /* pointer to application-specific server context */ - OSSL_CMP_CTX *ctx; /* Client CMP context, reusing transactionID etc. */ - int certReqId; /* id of last ir/cr/kur, OSSL_CMP_CERTREQID_NONE for p10cr */ + OSSL_CMP_CTX *ctx; /* CMP client context reused for transactionID etc. */ + void *custom_ctx; /* application-specific server context */ + int certReqId; /* of ir/cr/kur, OSSL_CMP_CERTREQID_NONE for p10cr */ + int polling; /* current transaction is in polling mode */ OSSL_CMP_SRV_cert_request_cb_t process_cert_request; OSSL_CMP_SRV_rr_cb_t process_rr; @@ -32,6 +33,8 @@ struct ossl_cmp_srv_ctx_st OSSL_CMP_SRV_error_cb_t process_error; OSSL_CMP_SRV_certConf_cb_t process_certConf; OSSL_CMP_SRV_pollReq_cb_t process_pollReq; + OSSL_CMP_SRV_delayed_delivery_cb_t delayed_delivery; + OSSL_CMP_SRV_clean_transaction_cb_t clean_transaction; int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */ int acceptUnprotected; /* Accept requests with no/invalid prot. */ @@ -59,6 +62,7 @@ OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL) goto err; ctx->certReqId = OSSL_CMP_CERTREQID_INVALID; + ctx->polling = 0; /* all other elements are initialized to 0 or NULL, respectively */ return ctx; @@ -89,6 +93,19 @@ int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx, return 1; } +int OSSL_CMP_SRV_CTX_init_trans(OSSL_CMP_SRV_CTX *srv_ctx, + OSSL_CMP_SRV_delayed_delivery_cb_t delay, + OSSL_CMP_SRV_clean_transaction_cb_t clean) +{ + if (srv_ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + srv_ctx->delayed_delivery = delay; + srv_ctx->clean_transaction = clean; + return 1; +} + OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx) { if (srv_ctx == NULL) { @@ -149,6 +166,46 @@ int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx, return 1; } +/* return error msg with waiting status if polling is initiated, else NULL */ +static OSSL_CMP_MSG *delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req) +{ + int ret; + unsigned long err; + int status = OSSL_CMP_PKISTATUS_waiting, + fail_info = 0, errorCode = 0; + const char *txt = NULL, *details = NULL; + OSSL_CMP_PKISI *si; + OSSL_CMP_MSG *msg; + + if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL + && srv_ctx->delayed_delivery != NULL)) + return NULL; + + ret = srv_ctx->delayed_delivery(srv_ctx, req); + if (ret == 0) + return NULL; + if (ret == 1) { + srv_ctx->polling = 1; + } else { + status = OSSL_CMP_PKISTATUS_rejection; + fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_systemFailure; + txt = "server application error"; + err = ERR_peek_error(); + errorCode = ERR_GET_REASON(err); + details = ERR_reason_error_string(err); + } + + si = OSSL_CMP_STATUSINFO_new(status, fail_info, txt); + if (si == NULL) + return NULL; + + msg = ossl_cmp_error_new(srv_ctx->ctx, si, errorCode, details, + srv_ctx->sendUnprotectedErrors); + OSSL_CMP_PKISI_free(si); + return msg; +} + /* * Processes an ir/cr/p10cr/kur and returns a certification response. * Only handles the first certification request contained in req @@ -195,15 +252,14 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED); return NULL; } - - if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) { + if ((crm = sk_OSSL_CRMF_MSG_value(reqs, 0)) == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND); return NULL; } certReqId = OSSL_CRMF_MSG_get_certReqId(crm); - if (certReqId != OSSL_CMP_CERTREQID) { + if (certReqId != OSSL_CMP_CERTREQID) { /* so far, only possible value */ ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); - return 0; + return NULL; } } srv_ctx->certReqId = certReqId; @@ -222,6 +278,8 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, &certOut, &chainOut, &caPubs); if (si == NULL) goto err; + if (ossl_cmp_pkisi_get_status(si) == OSSL_CMP_PKISTATUS_waiting) + srv_ctx->polling = 1; /* set OSSL_CMP_OPT_IMPLICIT_CONFIRM if and only if transaction ends */ if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM, @@ -265,9 +323,8 @@ static OSSL_CMP_MSG *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED); return NULL; } - - if ((details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr, - OSSL_CMP_REVREQSID)) == NULL) { + details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr, 0); + if (details == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); return NULL; } @@ -356,7 +413,7 @@ static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx, } else { if (num > 1) ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored"); - status = sk_OSSL_CMP_CERTSTATUS_value(ccc, OSSL_CMP_CERTREQID); + status = sk_OSSL_CMP_CERTSTATUS_value(ccc, 0); } if (status != NULL) { @@ -387,38 +444,96 @@ static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx, return msg; } +/* pollReq is handled separately, to avoid recursive call */ +static OSSL_CMP_MSG *process_non_polling_request(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_MSG *rsp = NULL; + + if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL + && req->body != NULL)) + return NULL; + + switch (OSSL_CMP_MSG_get_bodytype(req)) { + case OSSL_CMP_PKIBODY_IR: + case OSSL_CMP_PKIBODY_CR: + case OSSL_CMP_PKIBODY_P10CR: + case OSSL_CMP_PKIBODY_KUR: + if (srv_ctx->process_cert_request == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY); + else + rsp = process_cert_request(srv_ctx, req); + break; + case OSSL_CMP_PKIBODY_RR: + if (srv_ctx->process_rr == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY); + else + rsp = process_rr(srv_ctx, req); + break; + case OSSL_CMP_PKIBODY_GENM: + if (srv_ctx->process_genm == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY); + else + rsp = process_genm(srv_ctx, req); + break; + case OSSL_CMP_PKIBODY_ERROR: + if (srv_ctx->process_error == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY); + else + rsp = process_error(srv_ctx, req); + break; + case OSSL_CMP_PKIBODY_CERTCONF: + if (srv_ctx->process_certConf == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY); + else + rsp = process_certConf(srv_ctx, req); + break; + + case OSSL_CMP_PKIBODY_POLLREQ: + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + break; + default: + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY); + break; + } + + return rsp; +} + static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req) { OSSL_CMP_POLLREQCONTENT *prc; OSSL_CMP_POLLREQ *pr; int certReqId; - OSSL_CMP_MSG *certReq; + OSSL_CMP_MSG *orig_req; int64_t check_after = 0; OSSL_CMP_MSG *msg = NULL; if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL)) return NULL; + if (!srv_ctx->polling) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + return NULL; + } + prc = req->body->value.pollReq; if (sk_OSSL_CMP_POLLREQ_num(prc) != 1) { ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED); return NULL; } - pr = sk_OSSL_CMP_POLLREQ_value(prc, OSSL_CMP_CERTREQID); + pr = sk_OSSL_CMP_POLLREQ_value(prc, 0); certReqId = ossl_cmp_asn1_get_int(pr->certReqId); - if (certReqId != srv_ctx->certReqId) { - ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); - return NULL; - } if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId, - &certReq, &check_after)) + &orig_req, &check_after)) return NULL; - if (certReq != NULL) { - msg = process_cert_request(srv_ctx, certReq); - OSSL_CMP_MSG_free(certReq); + if (orig_req != NULL) { + srv_ctx->polling = 0; + msg = process_non_polling_request(srv_ctx, orig_req); + OSSL_CMP_MSG_free(orig_req); } else { if ((msg = ossl_cmp_pollRep_new(srv_ctx->ctx, certReqId, check_after)) == NULL) @@ -488,6 +603,12 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName)) goto err; + if (srv_ctx->polling && req_type != OSSL_CMP_PKIBODY_POLLREQ + && req_type != OSSL_CMP_PKIBODY_ERROR) { + ERR_raise(ERR_LIB_CMP, CMP_R_EXPECTED_POLLREQ); + goto err; + } + switch (req_type) { case OSSL_CMP_PKIBODY_IR: case OSSL_CMP_PKIBODY_CR: @@ -509,6 +630,13 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, if (!OSSL_CMP_CTX_set1_transactionID(ctx, NULL) || !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL)) goto err; + + if (srv_ctx->clean_transaction != NULL + && !srv_ctx->clean_transaction(srv_ctx, NULL)) { + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); + goto err; + } + break; default: /* transactionID should be already initialized */ @@ -528,50 +656,17 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, if (!req_verified) goto err; - switch (req_type) { - case OSSL_CMP_PKIBODY_IR: - case OSSL_CMP_PKIBODY_CR: - case OSSL_CMP_PKIBODY_P10CR: - case OSSL_CMP_PKIBODY_KUR: - if (srv_ctx->process_cert_request == NULL) - ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); - else - rsp = process_cert_request(srv_ctx, req); - break; - case OSSL_CMP_PKIBODY_RR: - if (srv_ctx->process_rr == NULL) - ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); - else - rsp = process_rr(srv_ctx, req); - break; - case OSSL_CMP_PKIBODY_GENM: - if (srv_ctx->process_genm == NULL) - ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); - else - rsp = process_genm(srv_ctx, req); - break; - case OSSL_CMP_PKIBODY_ERROR: - if (srv_ctx->process_error == NULL) - ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); - else - rsp = process_error(srv_ctx, req); - break; - case OSSL_CMP_PKIBODY_CERTCONF: - if (srv_ctx->process_certConf == NULL) - ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); - else - rsp = process_certConf(srv_ctx, req); - break; - case OSSL_CMP_PKIBODY_POLLREQ: + if (req_type == OSSL_CMP_PKIBODY_POLLREQ) { if (srv_ctx->process_pollReq == NULL) - ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY); else rsp = process_pollReq(srv_ctx, req); - break; - default: - /* Other request message types are not supported */ - ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); - break; + } else { + if (srv_ctx->delayed_delivery != NULL + && (rsp = delayed_delivery(srv_ctx, req)) != NULL) { + goto err; + } + rsp = process_non_polling_request(srv_ctx, req); } err: @@ -627,12 +722,19 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, break; /* fall through */ + case OSSL_CMP_PKIBODY_ERROR: + if (rsp != NULL && ossl_cmp_is_error_with_waiting(rsp)) + break; + /* fall through */ + case OSSL_CMP_PKIBODY_RP: case OSSL_CMP_PKIBODY_PKICONF: case OSSL_CMP_PKIBODY_GENP: - case OSSL_CMP_PKIBODY_ERROR: /* Other terminating response message types are not supported */ + srv_ctx->certReqId = OSSL_CMP_CERTREQID_INVALID; /* Prepare for next transaction, ignoring any errors here: */ + if (srv_ctx->clean_transaction != NULL) + (void)srv_ctx->clean_transaction(srv_ctx, ctx->transactionID); (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL); (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL); ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */ diff --git a/libs/openssl-3/crypto/cmp/cmp_vfy.c b/libs/openssl-3/crypto/cmp/cmp_vfy.c index 1869fae69..ec99ab7fe 100644 --- a/libs/openssl-3/crypto/cmp/cmp_vfy.c +++ b/libs/openssl-3/crypto/cmp/cmp_vfy.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2020 * Copyright Siemens AG 2015-2020 * @@ -175,8 +175,8 @@ static int check_name(const OSSL_CMP_CTX *ctx, int log_success, str = X509_NAME_oneline(actual_name, NULL, 0); if (X509_NAME_cmp(actual_name, expect_name) == 0) { if (log_success && str != NULL) - ossl_cmp_log2(INFO, ctx, " subject matches %s: %s", expect_desc, - str); + ossl_cmp_log3(INFO, ctx, " %s matches %s: %s", + actual_desc, expect_desc, str); OPENSSL_free(str); return 1; } @@ -424,14 +424,14 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, { int ret = 0; - if (mode_3gpp - && ((!ctx->permitTAInExtraCertsForIR - || OSSL_CMP_MSG_get_bodytype(msg) != OSSL_CMP_PKIBODY_IP))) + if (ctx->permitTAInExtraCertsForIR + && OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_IP) + ossl_cmp_info(ctx, mode_3gpp ? + "normal mode failed; trying now 3GPP mode trusting extraCerts" + : "trying first normal mode using trust store"); + else if (mode_3gpp) return 0; - ossl_cmp_info(ctx, - mode_3gpp ? "normal mode failed; trying now 3GPP mode trusting extraCerts" - : "trying first normal mode using trust store"); if (check_msg_with_certs(ctx, msg->extraCerts, "extraCerts", NULL, NULL, msg, mode_3gpp)) return 1; @@ -705,64 +705,89 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, { OSSL_CMP_PKIHEADER *hdr; const X509_NAME *expected_sender; + int num_untrusted, num_added, res; if (!ossl_assert(ctx != NULL && msg != NULL && msg->header != NULL)) return 0; hdr = OSSL_CMP_MSG_get0_header(msg); - /* validate sender name of received msg */ - if (hdr->sender->type != GEN_DIRNAME) { - ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); - return 0; - } - /* - * Compare actual sender name of response with expected sender name. - * Mitigates risk to accept misused PBM secret - * or misused certificate of an unauthorized entity of a trusted hierarchy. - */ + /* If expected_sender is given, validate sender name of received msg */ expected_sender = ctx->expected_sender; if (expected_sender == NULL && ctx->srvCert != NULL) expected_sender = X509_get_subject_name(ctx->srvCert); - if (!check_name(ctx, 0, "sender DN field", hdr->sender->d.directoryName, - "expected sender", expected_sender)) - return 0; + if (expected_sender != NULL) { + const X509_NAME *actual_sender; + char *str; + + if (hdr->sender->type != GEN_DIRNAME) { + ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); + return 0; + } + actual_sender = hdr->sender->d.directoryName; + /* + * Compare actual sender name of response with expected sender name. + * Mitigates risk of accepting misused PBM secret or + * misused certificate of an unauthorized entity of a trusted hierarchy. + */ + if (!check_name(ctx, 0, "sender DN field", actual_sender, + "expected sender", expected_sender)) { + str = X509_NAME_oneline(actual_sender, NULL, 0); + ERR_raise_data(ERR_LIB_CMP, CMP_R_UNEXPECTED_SENDER, + str != NULL ? str : ""); + OPENSSL_free(str); + return 0; + } + } /* Note: if recipient was NULL-DN it could be learned here if needed */ - if (sk_X509_num(msg->extraCerts) > 10) - ossl_cmp_warn(ctx, - "received CMP message contains more than 10 extraCerts"); + num_added = sk_X509_num(msg->extraCerts); + if (num_added > 10) + ossl_cmp_log1(WARN, ctx, "received CMP message contains %d extraCerts", + num_added); /* * Store any provided extraCerts in ctx for use in OSSL_CMP_validate_msg() * and for future use, such that they are available to ctx->certConf_cb and * the peer does not need to send them again in the same transaction. * Note that it does not help validating the message before storing the * extraCerts because they do not belong to the protected msg part anyway. - * For efficiency, the extraCerts are prepended so they get used first. + * The extraCerts are prepended. Allows simple removal if they shall not be + * cached. Also they get used first, which is likely good for efficiency. */ - if (!X509_add_certs(ctx->untrusted, msg->extraCerts, - /* this allows self-signed certs */ - X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP - | X509_ADD_FLAG_PREPEND)) + num_untrusted = ctx->untrusted == NULL ? 0 : sk_X509_num(ctx->untrusted); + res = ossl_x509_add_certs_new(&ctx->untrusted, msg->extraCerts, + /* this allows self-signed certs */ + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP + | X509_ADD_FLAG_PREPEND); + num_added = (ctx->untrusted == NULL ? 0 : sk_X509_num(ctx->untrusted)) + - num_untrusted; + if (!res) { + while (num_added-- > 0) + X509_free(sk_X509_shift(ctx->untrusted)); return 0; + } - /* validate message protection */ - if (hdr->protectionAlg != NULL) { - /* detect explicitly permitted exceptions for invalid protection */ - if (!OSSL_CMP_validate_msg(ctx, msg) - && (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) { -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_PROTECTION); - return 0; + if (hdr->protectionAlg != NULL) + res = OSSL_CMP_validate_msg(ctx, msg) + /* explicitly permitted exceptions for invalid protection: */ + || (cb != NULL && (*cb)(ctx, msg, 1, cb_arg) > 0); + else + /* explicitly permitted exceptions for missing protection: */ + res = cb != NULL && (*cb)(ctx, msg, 0, cb_arg) > 0; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + res = 1; /* support more aggressive fuzzing by letting invalid msg pass */ #endif - } - } else { - /* detect explicitly permitted exceptions for missing protection */ - if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) { -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + + /* remove extraCerts again if not caching */ + if (ctx->noCacheExtraCerts) + while (num_added-- > 0) + X509_free(sk_X509_shift(ctx->untrusted)); + + if (!res) { + if (hdr->protectionAlg != NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_PROTECTION); + else ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PROTECTION); - return 0; -#endif - } + return 0; } /* check CMP version number in header */ @@ -786,10 +811,26 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, CMP_R_TRANSACTIONID_UNMATCHED)) return 0; + /* + * enable clearing irrelevant errors + * in attempts to validate recipient nonce in case of delayed delivery. + */ + (void)ERR_set_mark(); /* compare received nonce with the one we sent */ if (!check_transactionID_or_nonce(ctx->senderNonce, hdr->recipNonce, - CMP_R_RECIPNONCE_UNMATCHED)) - return 0; + CMP_R_RECIPNONCE_UNMATCHED)) { + /* check if we are polling and received final response */ + if (ctx->first_senderNonce == NULL + || OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_POLLREP + /* compare received nonce with our sender nonce at poll start */ + || !check_transactionID_or_nonce(ctx->first_senderNonce, + hdr->recipNonce, + CMP_R_RECIPNONCE_UNMATCHED)) { + (void)ERR_clear_last_mark(); + return 0; + } + } + (void)ERR_pop_to_mark(); /* if not yet present, learn transactionID */ if (ctx->transactionID == NULL @@ -804,18 +845,6 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, if (!ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce)) return 0; - /* - * Store any provided extraCerts in ctx for future use, - * such that they are available to ctx->certConf_cb and - * the peer does not need to send them again in the same transaction. - * For efficiency, the extraCerts are prepended so they get used first. - */ - if (!X509_add_certs(ctx->untrusted, msg->extraCerts, - /* this allows self-signed certs */ - X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP - | X509_ADD_FLAG_PREPEND)) - return 0; - if (ossl_cmp_hdr_get_protection_nid(hdr) == NID_id_PasswordBasedMAC) { /* * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is diff --git a/libs/openssl-3/crypto/cms/cms_enc.c b/libs/openssl-3/crypto/cms/cms_enc.c index f42670cdf..ea8f07e1a 100644 --- a/libs/openssl-3/crypto/cms/cms_enc.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/cms/cms_pwri.c b/libs/openssl-3/crypto/cms/cms_pwri.c index 8b5beb215..67efa8766 100644 --- a/libs/openssl-3/crypto/cms/cms_pwri.c +++ b/libs/openssl-3/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. diff --git a/libs/openssl-3/crypto/cms/cms_smime.c b/libs/openssl-3/crypto/cms/cms_smime.c index 99a72f4df..3a8b13d6e 100644 --- a/libs/openssl-3/crypto/cms/cms_smime.c +++ b/libs/openssl-3/crypto/cms/cms_smime.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-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 @@ -236,7 +236,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, if (cms == NULL) return NULL; if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) - return NULL; + goto err; if (!(flags & CMS_DETACHED)) CMS_set_detached(cms, 0); @@ -245,6 +245,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, || CMS_final(cms, in, NULL, flags)) return cms; + err: CMS_ContentInfo_free(cms); return NULL; } diff --git a/libs/openssl-3/crypto/conf/conf_lib.c b/libs/openssl-3/crypto/conf/conf_lib.c index 62ac82729..601f49430 100644 --- a/libs/openssl-3/crypto/conf/conf_lib.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/conf/conf_mod.c b/libs/openssl-3/crypto/conf/conf_mod.c index d6a5f3ff3..a19575af3 100644 --- a/libs/openssl-3/crypto/conf/conf_mod.c +++ b/libs/openssl-3/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 #include #include @@ -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; } diff --git a/libs/openssl-3/crypto/conf/conf_sap.c b/libs/openssl-3/crypto/conf/conf_sap.c index 3019bcf31..6b3defe0f 100644 --- a/libs/openssl-3/crypto/conf/conf_sap.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/dh/dh_check.c b/libs/openssl-3/crypto/dh/dh_check.c index e20eb6208..ae23f6183 100644 --- a/libs/openssl-3/crypto/dh/dh_check.c +++ b/libs/openssl-3/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); diff --git a/libs/openssl-3/crypto/dh/dh_rfc5114.c b/libs/openssl-3/crypto/dh/dh_rfc5114.c index a44ff4716..7b1e0610b 100644 --- a/libs/openssl-3/crypto/dh/dh_rfc5114.c +++ b/libs/openssl-3/crypto/dh/dh_rfc5114.c @@ -18,7 +18,6 @@ #include "dh_local.h" #include #include "crypto/bn_dh.h" -#include "../crypto/bn/bn_local.h" /* * Macro to make a DH structure from BIGNUM data. NB: although just copying diff --git a/libs/openssl-3/crypto/dsa/dsa_check.c b/libs/openssl-3/crypto/dsa/dsa_check.c index 801b932d8..e1375dfad 100644 --- a/libs/openssl-3/crypto/dsa/dsa_check.c +++ b/libs/openssl-3/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); diff --git a/libs/openssl-3/crypto/dso/dso_dl.c b/libs/openssl-3/crypto/dso/dso_dl.c index ac9425480..451523911 100644 --- a/libs/openssl-3/crypto/dso/dso_dl.c +++ b/libs/openssl-3/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?" */ diff --git a/libs/openssl-3/crypto/dso/dso_dlfcn.c b/libs/openssl-3/crypto/dso/dso_dlfcn.c index 2befd6724..76737fa7b 100644 --- a/libs/openssl-3/crypto/dso/dso_dlfcn.c +++ b/libs/openssl-3/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" */ diff --git a/libs/openssl-3/crypto/ec/curve448/arch_32/f_impl.h b/libs/openssl-3/crypto/ec/curve448/arch_32/f_impl.h index b60f30b20..5cd25c04e 100644 --- a/libs/openssl-3/crypto/ec/curve448/arch_32/f_impl.h +++ b/libs/openssl-3/crypto/ec/curve448/arch_32/f_impl.h @@ -14,7 +14,7 @@ # define OSSL_CRYPTO_EC_CURVE448_ARCH_32_F_IMPL_H # define GF_HEADROOM 2 -# define LIMB(x) ((x##ULL) & ((1 << 28) - 1)), ((x##ULL) >> 28) +# define LIMB(x) ((x) & ((1 << 28) - 1)), ((x) >> 28) # define FIELD_LITERAL(a, b, c, d, e, f, g, h) \ {{LIMB(a), LIMB(b), LIMB(c), LIMB(d), LIMB(e), LIMB(f), LIMB(g), LIMB(h)}} diff --git a/libs/openssl-3/crypto/ec/curve448/arch_64/f_impl64.c b/libs/openssl-3/crypto/ec/curve448/arch_64/f_impl64.c index c944005da..06cc33a96 100644 --- a/libs/openssl-3/crypto/ec/curve448/arch_64/f_impl64.c +++ b/libs/openssl-3/crypto/ec/curve448/arch_64/f_impl64.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -45,9 +45,9 @@ void ossl_gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs) accum0 += widemul(a[j + 4], b[i - j + 4]); } for (; j < 4; j++) { - accum2 += widemul(a[j], b[i - j + 8]); - accum1 += widemul(aa[j], bbb[i - j + 4]); - accum0 += widemul(a[j + 4], bb[i - j + 4]); + accum2 += widemul(a[j], b[i + 8 - j]); + accum1 += widemul(aa[j], bbb[i + 4 - j]); + accum0 += widemul(a[j + 4], bb[i + 4 - j]); } accum1 -= accum2; diff --git a/libs/openssl-3/crypto/ec/curve448/curve448.c b/libs/openssl-3/crypto/ec/curve448/curve448.c index a69936067..2422d068a 100644 --- a/libs/openssl-3/crypto/ec/curve448/curve448.c +++ b/libs/openssl-3/crypto/ec/curve448/curve448.c @@ -28,8 +28,8 @@ static const curve448_scalar_t precomputed_scalarmul_adjustment = { { { - SC_LIMB(0xc873d6d54a7bb0cf), SC_LIMB(0xe933d8d723a70aad), - SC_LIMB(0xbb124b65129c96fd), SC_LIMB(0x00000008335dc163) + SC_LIMB(0xc873d6d54a7bb0cfULL), SC_LIMB(0xe933d8d723a70aadULL), + SC_LIMB(0xbb124b65129c96fdULL), SC_LIMB(0x00000008335dc163ULL) } } }; diff --git a/libs/openssl-3/crypto/ec/curve448/curve448_tables.c b/libs/openssl-3/crypto/ec/curve448/curve448_tables.c index c1e1d2d5e..0c6f626b3 100644 --- a/libs/openssl-3/crypto/ec/curve448/curve448_tables.c +++ b/libs/openssl-3/crypto/ec/curve448/curve448_tables.c @@ -16,1045 +16,1045 @@ static const curve448_precomputed_s curve448_precomputed_base_table = { { {{ - {FIELD_LITERAL(0x00cc3b062366f4cc, 0x003d6e34e314aa3c, - 0x00d51c0a7521774d, 0x0094e060eec6ab8b, - 0x00d21291b4d80082, 0x00befed12b55ef1e, - 0x00c3dd2df5c94518, 0x00e0a7b112b8d4e6)}, - {FIELD_LITERAL(0x0019eb5608d8723a, 0x00d1bab52fb3aedb, - 0x00270a7311ebc90c, 0x0037c12b91be7f13, - 0x005be16cd8b5c704, 0x003e181acda888e1, - 0x00bc1f00fc3fc6d0, 0x00d3839bfa319e20)}, - {FIELD_LITERAL(0x003caeb88611909f, 0x00ea8b378c4df3d4, - 0x00b3295b95a5a19a, 0x00a65f97514bdfb5, - 0x00b39efba743cab1, 0x0016ba98b862fd2d, - 0x0001508812ee71d7, 0x000a75740eea114a)}, - }}, {{ - {FIELD_LITERAL(0x00ebcf0eb649f823, 0x00166d332e98ea03, - 0x0059ddf64f5cd5f6, 0x0047763123d9471b, - 0x00a64065c53ef62f, 0x00978e44c480153d, - 0x000b5b2a0265f194, 0x0046a24b9f32965a)}, - {FIELD_LITERAL(0x00b9eef787034df0, 0x0020bc24de3390cd, - 0x000022160bae99bb, 0x00ae66e886e97946, - 0x0048d4bbe02cbb8b, 0x0072ba97b34e38d4, - 0x00eae7ec8f03e85a, 0x005ba92ecf808b2c)}, - {FIELD_LITERAL(0x00c9cfbbe74258fd, 0x00843a979ea9eaa7, - 0x000cbb4371cfbe90, 0x0059bac8f7f0a628, - 0x004b3dff882ff530, 0x0011869df4d90733, - 0x00595aa71f4abfc2, 0x0070e2d38990c2e6)}, - }}, {{ - {FIELD_LITERAL(0x00de2010c0a01733, 0x00c739a612e24297, - 0x00a7212643141d7c, 0x00f88444f6b67c11, - 0x00484b7b16ec28f2, 0x009c1b8856af9c68, - 0x00ff4669591fe9d6, 0x0054974be08a32c8)}, - {FIELD_LITERAL(0x0010de3fd682ceed, 0x008c07642d83ca4e, - 0x0013bb064e00a1cc, 0x009411ae27870e11, - 0x00ea8e5b4d531223, 0x0032fe7d2aaece2e, - 0x00d989e243e7bb41, 0x000fe79a508e9b8b)}, - {FIELD_LITERAL(0x005e0426b9bfc5b1, 0x0041a5b1d29ee4fa, - 0x0015b0def7774391, 0x00bc164f1f51af01, - 0x00d543b0942797b9, 0x003c129b6398099c, - 0x002b114c6e5adf18, 0x00b4e630e4018a7b)}, - }}, {{ - {FIELD_LITERAL(0x00d490afc95f8420, 0x00b096bf50c1d9b9, - 0x00799fd707679866, 0x007c74d9334afbea, - 0x00efaa8be80ff4ed, 0x0075c4943bb81694, - 0x00c21c2fca161f36, 0x00e77035d492bfee)}, - {FIELD_LITERAL(0x006658a190dd6661, 0x00e0e9bab38609a6, - 0x0028895c802237ed, 0x006a0229c494f587, - 0x002dcde96c9916b7, 0x00d158822de16218, - 0x00173b917a06856f, 0x00ca78a79ae07326)}, - {FIELD_LITERAL(0x00e35bfc79caced4, 0x0087238a3e1fe3bb, - 0x00bcbf0ff4ceff5b, 0x00a19c1c94099b91, - 0x0071e102b49db976, 0x0059e3d004eada1e, - 0x008da78afa58a47e, 0x00579c8ebf269187)}, - }}, {{ - {FIELD_LITERAL(0x00a16c2905eee75f, 0x009d4bcaea2c7e1d, - 0x00d3bd79bfad19df, 0x0050da745193342c, - 0x006abdb8f6b29ab1, 0x00a24fe0a4fef7ef, - 0x0063730da1057dfb, 0x00a08c312c8eb108)}, - {FIELD_LITERAL(0x00b583be005375be, 0x00a40c8f8a4e3df4, - 0x003fac4a8f5bdbf7, 0x00d4481d872cd718, - 0x004dc8749cdbaefe, 0x00cce740d5e5c975, - 0x000b1c1f4241fd21, 0x00a76de1b4e1cd07)}, - {FIELD_LITERAL(0x007a076500d30b62, 0x000a6e117b7f090f, - 0x00c8712ae7eebd9a, 0x000fbd6c1d5f6ff7, - 0x003a7977246ebf11, 0x00166ed969c6600e, - 0x00aa42e469c98bec, 0x00dc58f307cf0666)}, - }}, {{ - {FIELD_LITERAL(0x004b491f65a9a28b, 0x006a10309e8a55b7, - 0x00b67210185187ef, 0x00cf6497b12d9b8f, - 0x0085778c56e2b1ba, 0x0015b4c07a814d85, - 0x00686479e62da561, 0x008de5d88f114916)}, - {FIELD_LITERAL(0x00e37c88d6bba7b1, 0x003e4577e1b8d433, - 0x0050d8ea5f510ec0, 0x0042fc9f2da9ef59, - 0x003bd074c1141420, 0x00561b8b7b68774e, - 0x00232e5e5d1013a3, 0x006b7f2cb3d7e73f)}, - {FIELD_LITERAL(0x004bdd0f0b41e6a0, 0x001773057c405d24, - 0x006029f99915bd97, 0x006a5ba70a17fe2f, - 0x0046111977df7e08, 0x004d8124c89fb6b7, - 0x00580983b2bb2724, 0x00207bf330d6f3fe)}, - }}, {{ - {FIELD_LITERAL(0x007efdc93972a48b, 0x002f5e50e78d5fee, - 0x0080dc11d61c7fe5, 0x0065aa598707245b, - 0x009abba2300641be, 0x000c68787656543a, - 0x00ffe0fef2dc0a17, 0x00007ffbd6cb4f3a)}, - {FIELD_LITERAL(0x0036012f2b836efc, 0x00458c126d6b5fbc, - 0x00a34436d719ad1e, 0x0097be6167117dea, - 0x0009c219c879cff3, 0x0065564493e60755, - 0x00993ac94a8cdec0, 0x002d4885a4d0dbaf)}, - {FIELD_LITERAL(0x00598b60b4c068ba, 0x00c547a0be7f1afd, - 0x009582164acf12af, 0x00af4acac4fbbe40, - 0x005f6ca7c539121a, 0x003b6e752ebf9d66, - 0x00f08a30d5cac5d4, 0x00e399bb5f97c5a9)}, - }}, {{ - {FIELD_LITERAL(0x007445a0409c0a66, 0x00a65c369f3829c0, - 0x0031d248a4f74826, 0x006817f34defbe8e, - 0x00649741d95ebf2e, 0x00d46466ab16b397, - 0x00fdc35703bee414, 0x00343b43334525f8)}, - {FIELD_LITERAL(0x001796bea93f6401, 0x00090c5a42e85269, - 0x00672412ba1252ed, 0x001201d47b6de7de, - 0x006877bccfe66497, 0x00b554fd97a4c161, - 0x009753f42dbac3cf, 0x00e983e3e378270a)}, - {FIELD_LITERAL(0x00ac3eff18849872, 0x00f0eea3bff05690, - 0x00a6d72c21dd505d, 0x001b832642424169, - 0x00a6813017b540e5, 0x00a744bd71b385cd, - 0x0022a7d089130a7b, 0x004edeec9a133486)}, - }}, {{ - {FIELD_LITERAL(0x00b2d6729196e8a9, 0x0088a9bb2031cef4, - 0x00579e7787dc1567, 0x0030f49feb059190, - 0x00a0b1d69c7f7d8f, 0x0040bdcc6d9d806f, - 0x00d76c4037edd095, 0x00bbf24376415dd7)}, - {FIELD_LITERAL(0x00240465ff5a7197, 0x00bb97e76caf27d0, - 0x004b4edbf8116d39, 0x001d8586f708cbaa, - 0x000f8ee8ff8e4a50, 0x00dde5a1945dd622, - 0x00e6fc1c0957e07c, 0x0041c9cdabfd88a0)}, - {FIELD_LITERAL(0x005344b0bf5b548c, 0x002957d0b705cc99, - 0x00f586a70390553d, 0x0075b3229f583cc3, - 0x00a1aa78227490e4, 0x001bf09cf7957717, - 0x00cf6bf344325f52, 0x0065bd1c23ca3ecf)}, - }}, {{ - {FIELD_LITERAL(0x009bff3b3239363c, 0x00e17368796ef7c0, - 0x00528b0fe0971f3a, 0x0008014fc8d4a095, - 0x00d09f2e8a521ec4, 0x006713ab5dde5987, - 0x0003015758e0dbb1, 0x00215999f1ba212d)}, - {FIELD_LITERAL(0x002c88e93527da0e, 0x0077c78f3456aad5, - 0x0071087a0a389d1c, 0x00934dac1fb96dbd, - 0x008470e801162697, 0x005bc2196cd4ad49, - 0x00e535601d5087c3, 0x00769888700f497f)}, - {FIELD_LITERAL(0x00da7a4b557298ad, 0x0019d2589ea5df76, - 0x00ef3e38be0c6497, 0x00a9644e1312609a, - 0x004592f61b2558da, 0x0082c1df510d7e46, - 0x0042809a535c0023, 0x00215bcb5afd7757)}, - }}, {{ - {FIELD_LITERAL(0x002b9df55a1a4213, 0x00dcfc3b464a26be, - 0x00c4f9e07a8144d5, 0x00c8e0617a92b602, - 0x008e3c93accafae0, 0x00bf1bcb95b2ca60, - 0x004ce2426a613bf3, 0x00266cac58e40921)}, - {FIELD_LITERAL(0x008456d5db76e8f0, 0x0032ca9cab2ce163, - 0x0059f2b8bf91abcf, 0x0063c2a021712788, - 0x00f86155af22f72d, 0x00db98b2a6c005a0, - 0x00ac6e416a693ac4, 0x007a93572af53226)}, - {FIELD_LITERAL(0x0087767520f0de22, 0x0091f64012279fb5, - 0x001050f1f0644999, 0x004f097a2477ad3c, - 0x006b37913a9947bd, 0x001a3d78645af241, - 0x0057832bbb3008a7, 0x002c1d902b80dc20)}, - }}, {{ - {FIELD_LITERAL(0x001a6002bf178877, 0x009bce168aa5af50, - 0x005fc318ff04a7f5, 0x0052818f55c36461, - 0x008768f5d4b24afb, 0x0037ffbae7b69c85, - 0x0018195a4b61edc0, 0x001e12ea088434b2)}, - {FIELD_LITERAL(0x0047d3f804e7ab07, 0x00a809ab5f905260, - 0x00b3ffc7cdaf306d, 0x00746e8ec2d6e509, - 0x00d0dade8887a645, 0x00acceeebde0dd37, - 0x009bc2579054686b, 0x0023804f97f1c2bf)}, - {FIELD_LITERAL(0x0043e2e2e50b80d7, 0x00143aafe4427e0f, - 0x005594aaecab855b, 0x008b12ccaaecbc01, - 0x002deeb091082bc3, 0x009cca4be2ae7514, - 0x00142b96e696d047, 0x00ad2a2b1c05256a)}, - }}, {{ - {FIELD_LITERAL(0x003914f2f144b78b, 0x007a95dd8bee6f68, - 0x00c7f4384d61c8e6, 0x004e51eb60f1bdb2, - 0x00f64be7aa4621d8, 0x006797bfec2f0ac0, - 0x007d17aab3c75900, 0x001893e73cac8bc5)}, - {FIELD_LITERAL(0x00140360b768665b, 0x00b68aca4967f977, - 0x0001089b66195ae4, 0x00fe71122185e725, - 0x000bca2618d49637, 0x00a54f0557d7e98a, - 0x00cdcd2f91d6f417, 0x00ab8c13741fd793)}, - {FIELD_LITERAL(0x00725ee6b1e549e0, 0x007124a0769777fa, - 0x000b68fdad07ae42, 0x0085b909cd4952df, - 0x0092d2e3c81606f4, 0x009f22f6cac099a0, - 0x00f59da57f2799a8, 0x00f06c090122f777)}, - }}, {{ - {FIELD_LITERAL(0x00ce0bed0a3532bc, 0x001a5048a22df16b, - 0x00e31db4cbad8bf1, 0x00e89292120cf00e, - 0x007d1dd1a9b00034, 0x00e2a9041ff8f680, - 0x006a4c837ae596e7, 0x00713af1068070b3)}, - {FIELD_LITERAL(0x00c4fe64ce66d04b, 0x00b095d52e09b3d7, - 0x00758bbecb1a3a8e, 0x00f35cce8d0650c0, - 0x002b878aa5984473, 0x0062e0a3b7544ddc, - 0x00b25b290ed116fe, 0x007b0f6abe0bebf2)}, - {FIELD_LITERAL(0x0081d4e3addae0a8, 0x003410c836c7ffcc, - 0x00c8129ad89e4314, 0x000e3d5a23922dcd, - 0x00d91e46f29c31f3, 0x006c728cde8c5947, - 0x002bc655ba2566c0, 0x002ca94721533108)}, - }}, {{ - {FIELD_LITERAL(0x0051e4b3f764d8a9, 0x0019792d46e904a0, - 0x00853bc13dbc8227, 0x000840208179f12d, - 0x0068243474879235, 0x0013856fbfe374d0, - 0x00bda12fe8676424, 0x00bbb43635926eb2)}, - {FIELD_LITERAL(0x0012cdc880a93982, 0x003c495b21cd1b58, - 0x00b7e5c93f22a26e, 0x0044aa82dfb99458, - 0x009ba092cdffe9c0, 0x00a14b3ab2083b73, - 0x000271c2f70e1c4b, 0x00eea9cac0f66eb8)}, - {FIELD_LITERAL(0x001a1847c4ac5480, 0x00b1b412935bb03a, - 0x00f74285983bf2b2, 0x00624138b5b5d0f1, - 0x008820c0b03d38bf, 0x00b94e50a18c1572, - 0x0060f6934841798f, 0x00c52f5d66d6ebe2)}, - }}, {{ - {FIELD_LITERAL(0x00da23d59f9bcea6, 0x00e0f27007a06a4b, - 0x00128b5b43a6758c, 0x000cf50190fa8b56, - 0x00fc877aba2b2d72, 0x00623bef52edf53f, - 0x00e6af6b819669e2, 0x00e314dc34fcaa4f)}, - {FIELD_LITERAL(0x0066e5eddd164d1e, 0x00418a7c6fe28238, - 0x0002e2f37e962c25, 0x00f01f56b5975306, - 0x0048842fa503875c, 0x0057b0e968078143, - 0x00ff683024f3d134, 0x0082ae28fcad12e4)}, - {FIELD_LITERAL(0x0011ddfd21260e42, 0x00d05b0319a76892, - 0x00183ea4368e9b8f, 0x00b0815662affc96, - 0x00b466a5e7ce7c88, 0x00db93b07506e6ee, - 0x0033885f82f62401, 0x0086f9090ec9b419)}, - }}, {{ - {FIELD_LITERAL(0x00d95d1c5fcb435a, 0x0016d1ed6b5086f9, - 0x00792aa0b7e54d71, 0x0067b65715f1925d, - 0x00a219755ec6176b, 0x00bc3f026b12c28f, - 0x00700c897ffeb93e, 0x0089b83f6ec50b46)}, - {FIELD_LITERAL(0x003c97e6384da36e, 0x00423d53eac81a09, - 0x00b70d68f3cdce35, 0x00ee7959b354b92c, - 0x00f4e9718819c8ca, 0x009349f12acbffe9, - 0x005aee7b62cb7da6, 0x00d97764154ffc86)}, - {FIELD_LITERAL(0x00526324babb46dc, 0x002ee99b38d7bf9e, - 0x007ea51794706ef4, 0x00abeb04da6e3c39, - 0x006b457c1d281060, 0x00fe243e9a66c793, - 0x00378de0fb6c6ee4, 0x003e4194b9c3cb93)}, - }}, {{ - {FIELD_LITERAL(0x00fed3cd80ca2292, 0x0015b043a73ca613, - 0x000a9fd7bf9be227, 0x003b5e03de2db983, - 0x005af72d46904ef7, 0x00c0f1b5c49faa99, - 0x00dc86fc3bd305e1, 0x00c92f08c1cb1797)}, - {FIELD_LITERAL(0x0079680ce111ed3b, 0x001a1ed82806122c, - 0x000c2e7466d15df3, 0x002c407f6f7150fd, - 0x00c5e7c96b1b0ce3, 0x009aa44626863ff9, - 0x00887b8b5b80be42, 0x00b6023cec964825)}, - {FIELD_LITERAL(0x00e4a8e1048970c8, 0x0062887b7830a302, - 0x00bcf1c8cd81402b, 0x0056dbb81a68f5be, - 0x0014eced83f12452, 0x00139e1a510150df, - 0x00bb81140a82d1a3, 0x000febcc1aaf1aa7)}, - }}, {{ - {FIELD_LITERAL(0x00a7527958238159, 0x0013ec9537a84cd6, - 0x001d7fee7d562525, 0x00b9eefa6191d5e5, - 0x00dbc97db70bcb8a, 0x00481affc7a4d395, - 0x006f73d3e70c31bb, 0x00183f324ed96a61)}, - {FIELD_LITERAL(0x0039dd7ce7fc6860, 0x00d64f6425653da1, - 0x003e037c7f57d0af, 0x0063477a06e2bcf2, - 0x001727dbb7ac67e6, 0x0049589f5efafe2e, - 0x00fc0fef2e813d54, 0x008baa5d087fb50d)}, - {FIELD_LITERAL(0x0024fb59d9b457c7, 0x00a7d4e060223e4c, - 0x00c118d1b555fd80, 0x0082e216c732f22a, - 0x00cd2a2993089504, 0x003638e836a3e13d, - 0x000d855ee89b4729, 0x008ec5b7d4810c91)}, - }}, {{ - {FIELD_LITERAL(0x001bf51f7d65cdfd, 0x00d14cdafa16a97d, - 0x002c38e60fcd10e7, 0x00a27446e393efbd, - 0x000b5d8946a71fdd, 0x0063df2cde128f2f, - 0x006c8679569b1888, 0x0059ffc4925d732d)}, - {FIELD_LITERAL(0x00ece96f95f2b66f, 0x00ece7952813a27b, - 0x0026fc36592e489e, 0x007157d1a2de0f66, - 0x00759dc111d86ddf, 0x0012881e5780bb0f, - 0x00c8ccc83ad29496, 0x0012b9bd1929eb71)}, - {FIELD_LITERAL(0x000fa15a20da5df0, 0x00349ddb1a46cd31, - 0x002c512ad1d8e726, 0x00047611f669318d, - 0x009e68fba591e17e, 0x004320dffa803906, - 0x00a640874951a3d3, 0x00b6353478baa24f)}, - }}, {{ - {FIELD_LITERAL(0x009696510000d333, 0x00ec2f788bc04826, - 0x000e4d02b1f67ba5, 0x00659aa8dace08b6, - 0x00d7a38a3a3ae533, 0x008856defa8c746b, - 0x004d7a4402d3da1a, 0x00ea82e06229260f)}, - {FIELD_LITERAL(0x006a15bb20f75c0c, 0x0079a144027a5d0c, - 0x00d19116ce0b4d70, 0x0059b83bcb0b268e, - 0x005f58f63f16c127, 0x0079958318ee2c37, - 0x00defbb063d07f82, 0x00f1f0b931d2d446)}, - {FIELD_LITERAL(0x00cb5e4c3c35d422, 0x008df885ca43577f, - 0x00fa50b16ca3e471, 0x005a0e58e17488c8, - 0x00b2ceccd6d34d19, 0x00f01d5d235e36e9, - 0x00db2e7e4be6ca44, 0x00260ab77f35fccd)}, - }}, {{ - {FIELD_LITERAL(0x006f6fd9baac61d5, 0x002a7710a020a895, - 0x009de0db7fc03d4d, 0x00cdedcb1875f40b, - 0x00050caf9b6b1e22, 0x005e3a6654456ab0, - 0x00775fdf8c4423d4, 0x0028701ea5738b5d)}, - {FIELD_LITERAL(0x009ffd90abfeae96, 0x00cba3c2b624a516, - 0x005ef08bcee46c91, 0x00e6fde30afb6185, - 0x00f0b4db4f818ce4, 0x006c54f45d2127f5, - 0x00040125035854c7, 0x00372658a3287e13)}, - {FIELD_LITERAL(0x00d7070fb1beb2ab, 0x0078fc845a93896b, - 0x006894a4b2f224a6, 0x005bdd8192b9dbde, - 0x00b38839874b3a9e, 0x00f93618b04b7a57, - 0x003e3ec75fd2c67e, 0x00bf5e6bfc29494a)}, - }}, {{ - {FIELD_LITERAL(0x00f19224ebba2aa5, 0x0074f89d358e694d, - 0x00eea486597135ad, 0x0081579a4555c7e1, - 0x0010b9b872930a9d, 0x00f002e87a30ecc0, - 0x009b9d66b6de56e2, 0x00a3c4f45e8004eb)}, - {FIELD_LITERAL(0x0045e8dda9400888, 0x002ff12e5fc05db7, - 0x00a7098d54afe69c, 0x00cdbe846a500585, - 0x00879c1593ca1882, 0x003f7a7fea76c8b0, - 0x002cd73dd0c8e0a1, 0x00645d6ce96f51fe)}, - {FIELD_LITERAL(0x002b7e83e123d6d6, 0x00398346f7419c80, - 0x0042922e55940163, 0x005e7fc5601886a3, - 0x00e88f2cee1d3103, 0x00e7fab135f2e377, - 0x00b059984dbf0ded, 0x0009ce080faa5bb8)}, - }}, {{ - {FIELD_LITERAL(0x0085e78af7758979, 0x00275a4ee1631a3a, - 0x00d26bc0ed78b683, 0x004f8355ea21064f, - 0x00d618e1a32696e5, 0x008d8d7b150e5680, - 0x00a74cd854b278d2, 0x001dd62702203ea0)}, - {FIELD_LITERAL(0x00f89335c2a59286, 0x00a0f5c905d55141, - 0x00b41fb836ee9382, 0x00e235d51730ca43, - 0x00a5cb37b5c0a69a, 0x009b966ffe136c45, - 0x00cb2ea10bf80ed1, 0x00fb2b370b40dc35)}, - {FIELD_LITERAL(0x00d687d16d4ee8ba, 0x0071520bdd069dff, - 0x00de85c60d32355d, 0x0087d2e3565102f4, - 0x00cde391b8dfc9aa, 0x00e18d69efdfefe5, - 0x004a9d0591954e91, 0x00fa36dd8b50eee5)}, - }}, {{ - {FIELD_LITERAL(0x002e788749a865f7, 0x006e4dc3116861ea, - 0x009f1428c37276e6, 0x00e7d2e0fc1e1226, - 0x003aeebc6b6c45f6, 0x0071a8073bf500c9, - 0x004b22ad986b530c, 0x00f439e63c0d79d4)}, - {FIELD_LITERAL(0x006bc3d53011f470, 0x00032d6e692b83e8, - 0x00059722f497cd0b, 0x0009b4e6f0c497cc, - 0x0058a804b7cce6c0, 0x002b71d3302bbd5d, - 0x00e2f82a36765fce, 0x008dded99524c703)}, - {FIELD_LITERAL(0x004d058953747d64, 0x00701940fe79aa6f, - 0x00a620ac71c760bf, 0x009532b611158b75, - 0x00547ed7f466f300, 0x003cb5ab53a8401a, - 0x00c7763168ce3120, 0x007e48e33e4b9ab2)}, - }}, {{ - {FIELD_LITERAL(0x001b2fc57bf3c738, 0x006a3f918993fb80, - 0x0026f7a14fdec288, 0x0075a2cdccef08db, - 0x00d3ecbc9eecdbf1, 0x0048c40f06e5bf7f, - 0x00d63e423009896b, 0x000598bc99c056a8)}, - {FIELD_LITERAL(0x002f194eaafa46dc, 0x008e38f57fe87613, - 0x00dc8e5ae25f4ab2, 0x000a17809575e6bd, - 0x00d3ec7923ba366a, 0x003a7e72e0ad75e3, - 0x0010024b88436e0a, 0x00ed3c5444b64051)}, - {FIELD_LITERAL(0x00831fc1340af342, 0x00c9645669466d35, - 0x007692b4cc5a080f, 0x009fd4a47ac9259f, - 0x001eeddf7d45928b, 0x003c0446fc45f28b, - 0x002c0713aa3e2507, 0x0095706935f0f41e)}, - }}, {{ - {FIELD_LITERAL(0x00766ae4190ec6d8, 0x0065768cabc71380, - 0x00b902598416cdc2, 0x00380021ad38df52, - 0x008f0b89d6551134, 0x004254d4cc62c5a5, - 0x000d79f4484b9b94, 0x00b516732ae3c50e)}, - {FIELD_LITERAL(0x001fb73475c45509, 0x00d2b2e5ea43345a, - 0x00cb3c3842077bd1, 0x0029f90ad820946e, - 0x007c11b2380778aa, 0x009e54ece62c1704, - 0x004bc60c41ca01c3, 0x004525679a5a0b03)}, - {FIELD_LITERAL(0x00c64fbddbed87b3, 0x0040601d11731faa, - 0x009c22475b6f9d67, 0x0024b79dae875f15, - 0x00616fed3f02c3b0, 0x0000cf39f6af2d3b, - 0x00c46bac0aa9a688, 0x00ab23e2800da204)}, - }}, {{ - {FIELD_LITERAL(0x000b3a37617632b0, 0x00597199fe1cfb6c, - 0x0042a7ccdfeafdd6, 0x004cc9f15ebcea17, - 0x00f436e596a6b4a4, 0x00168861142df0d8, - 0x000753edfec26af5, 0x000c495d7e388116)}, - {FIELD_LITERAL(0x0017085f4a346148, 0x00c7cf7a37f62272, - 0x001776e129bc5c30, 0x009955134c9eef2a, - 0x001ba5bdf1df07be, 0x00ec39497103a55c, - 0x006578354fda6cfb, 0x005f02719d4f15ee)}, - {FIELD_LITERAL(0x0052b9d9b5d9655d, 0x00d4ec7ba1b461c3, - 0x00f95df4974f280b, 0x003d8e5ca11aeb51, - 0x00d4981eb5a70b26, 0x000af9a4f6659f29, - 0x004598c846faeb43, 0x0049d9a183a47670)}, - }}, {{ - {FIELD_LITERAL(0x000a72d23dcb3f1f, 0x00a3737f84011727, - 0x00f870c0fbbf4a47, 0x00a7aadd04b5c9ca, - 0x000c7715c67bd072, 0x00015a136afcd74e, - 0x0080d5caea499634, 0x0026b448ec7514b7)}, - {FIELD_LITERAL(0x00b60167d9e7d065, 0x00e60ba0d07381e8, - 0x003a4f17b725c2d4, 0x006c19fe176b64fa, - 0x003b57b31af86ccb, 0x0021047c286180fd, - 0x00bdc8fb00c6dbb6, 0x00fe4a9f4bab4f3f)}, - {FIELD_LITERAL(0x0088ffc3a16111f7, 0x009155e4245d0bc8, - 0x00851d68220572d5, 0x00557ace1e514d29, - 0x0031d7c339d91022, 0x00101d0ae2eaceea, - 0x00246ab3f837b66a, 0x00d5216d381ff530)}, - }}, {{ - {FIELD_LITERAL(0x0057e7ea35f36dae, 0x00f47d7ad15de22e, - 0x00d757ea4b105115, 0x008311457d579d7e, - 0x00b49b75b1edd4eb, 0x0081c7ff742fd63a, - 0x00ddda3187433df6, 0x00475727d55f9c66)}, - {FIELD_LITERAL(0x00a6295218dc136a, 0x00563b3af0e9c012, - 0x00d3753b0145db1b, 0x004550389c043dc1, - 0x00ea94ae27401bdf, 0x002b0b949f2b7956, - 0x00c63f780ad8e23c, 0x00e591c47d6bab15)}, - {FIELD_LITERAL(0x00416c582b058eb6, 0x004107da5b2cc695, - 0x00b3cd2556aeec64, 0x00c0b418267e57a1, - 0x001799293579bd2e, 0x0046ed44590e4d07, - 0x001d7459b3630a1e, 0x00c6afba8b6696aa)}, - }}, {{ - {FIELD_LITERAL(0x008d6009b26da3f8, 0x00898e88ca06b1ca, - 0x00edb22b2ed7fe62, 0x00fbc93516aabe80, - 0x008b4b470c42ce0d, 0x00e0032ba7d0dcbb, - 0x00d76da3a956ecc8, 0x007f20fe74e3852a)}, - {FIELD_LITERAL(0x002419222c607674, 0x00a7f23af89188b3, - 0x00ad127284e73d1c, 0x008bba582fae1c51, - 0x00fc6aa7ca9ecab1, 0x003df5319eb6c2ba, - 0x002a05af8a8b199a, 0x004bf8354558407c)}, - {FIELD_LITERAL(0x00ce7d4a30f0fcbf, 0x00d02c272629f03d, - 0x0048c001f7400bc2, 0x002c21368011958d, - 0x0098a550391e96b5, 0x002d80b66390f379, - 0x001fa878760cc785, 0x001adfce54b613d5)}, - }}, {{ - {FIELD_LITERAL(0x001ed4dc71fa2523, 0x005d0bff19bf9b5c, - 0x00c3801cee065a64, 0x001ed0b504323fbf, - 0x0003ab9fdcbbc593, 0x00df82070178b8d2, - 0x00a2bcaa9c251f85, 0x00c628a3674bd02e)}, - {FIELD_LITERAL(0x006b7a0674f9f8de, 0x00a742414e5c7cff, - 0x0041cbf3c6e13221, 0x00e3a64fd207af24, - 0x0087c05f15fbe8d1, 0x004c50936d9e8a33, - 0x001306ec21042b6d, 0x00a4f4137d1141c2)}, - {FIELD_LITERAL(0x0009e6fb921568b0, 0x00b3c60120219118, - 0x002a6c3460dd503a, 0x009db1ef11654b54, - 0x0063e4bf0be79601, 0x00670d34bb2592b9, - 0x00dcee2f6c4130ce, 0x00b2682e88e77f54)}, - }}, {{ - {FIELD_LITERAL(0x000d5b4b3da135ab, 0x00838f3e5064d81d, - 0x00d44eb50f6d94ed, 0x0008931ab502ac6d, - 0x00debe01ca3d3586, 0x0025c206775f0641, - 0x005ad4b6ae912763, 0x007e2c318ad8f247)}, - {FIELD_LITERAL(0x00ddbe0750dd1add, 0x004b3c7b885844b8, - 0x00363e7ecf12f1ae, 0x0062e953e6438f9d, - 0x0023cc73b076afe9, 0x00b09fa083b4da32, - 0x00c7c3d2456c541d, 0x005b591ec6b694d4)}, - {FIELD_LITERAL(0x0028656e19d62fcf, 0x0052a4af03df148d, - 0x00122765ddd14e42, 0x00f2252904f67157, - 0x004741965b636f3a, 0x006441d296132cb9, - 0x005e2106f956a5b7, 0x00247029592d335c)}, - }}, {{ - {FIELD_LITERAL(0x003fe038eb92f894, 0x000e6da1b72e8e32, - 0x003a1411bfcbe0fa, 0x00b55d473164a9e4, - 0x00b9a775ac2df48d, 0x0002ddf350659e21, - 0x00a279a69eb19cb3, 0x00f844eab25cba44)}, - {FIELD_LITERAL(0x00c41d1f9c1f1ac1, 0x007b2df4e9f19146, - 0x00b469355fd5ba7a, 0x00b5e1965afc852a, - 0x00388d5f1e2d8217, 0x0022079e4c09ae93, - 0x0014268acd4ef518, 0x00c1dd8d9640464c)}, - {FIELD_LITERAL(0x0038526adeed0c55, 0x00dd68c607e3fe85, - 0x00f746ddd48a5d57, 0x0042f2952b963b7c, - 0x001cbbd6876d5ec2, 0x005e341470bca5c2, - 0x00871d41e085f413, 0x00e53ab098f45732)}, - }}, {{ - {FIELD_LITERAL(0x004d51124797c831, 0x008f5ae3750347ad, - 0x0070ced94c1a0c8e, 0x00f6db2043898e64, - 0x000d00c9a5750cd0, 0x000741ec59bad712, - 0x003c9d11aab37b7f, 0x00a67ba169807714)}, - {FIELD_LITERAL(0x00adb2c1566e8b8f, 0x0096c68a35771a9a, - 0x00869933356f334a, 0x00ba9c93459f5962, - 0x009ec73fb6e8ca4b, 0x003c3802c27202e1, - 0x0031f5b733e0c008, 0x00f9058c19611fa9)}, - {FIELD_LITERAL(0x00238f01814a3421, 0x00c325a44b6cce28, - 0x002136f97aeb0e73, 0x000cac8268a4afe2, - 0x0022fd218da471b3, 0x009dcd8dfff8def9, - 0x00cb9f8181d999bb, 0x00143ae56edea349)}, - }}, {{ - {FIELD_LITERAL(0x0000623bf87622c5, 0x00a1966fdd069496, - 0x00c315b7b812f9fc, 0x00bdf5efcd128b97, - 0x001d464f532e3e16, 0x003cd94f081bfd7e, - 0x00ed9dae12ce4009, 0x002756f5736eee70)}, - {FIELD_LITERAL(0x00a5187e6ee7341b, 0x00e6d52e82d83b6e, - 0x00df3c41323094a7, 0x00b3324f444e9de9, - 0x00689eb21a35bfe5, 0x00f16363becd548d, - 0x00e187cc98e7f60f, 0x00127d9062f0ccab)}, - {FIELD_LITERAL(0x004ad71b31c29e40, 0x00a5fcace12fae29, - 0x004425b5597280ed, 0x00e7ef5d716c3346, - 0x0010b53ada410ac8, 0x0092310226060c9b, - 0x0091c26128729c7e, 0x0088b42900f8ec3b)}, - }}, {{ - {FIELD_LITERAL(0x00f1e26e9762d4a8, 0x00d9d74082183414, - 0x00ffec9bd57a0282, 0x000919e128fd497a, - 0x00ab7ae7d00fe5f8, 0x0054dc442851ff68, - 0x00c9ebeb3b861687, 0x00507f7cab8b698f)}, - {FIELD_LITERAL(0x00c13c5aae3ae341, 0x009c6c9ed98373e7, - 0x00098f26864577a8, 0x0015b886e9488b45, - 0x0037692c42aadba5, 0x00b83170b8e7791c, - 0x001670952ece1b44, 0x00fd932a39276da2)}, - {FIELD_LITERAL(0x0081a3259bef3398, 0x005480fff416107b, - 0x00ce4f607d21be98, 0x003ffc084b41df9b, - 0x0043d0bb100502d1, 0x00ec35f575ba3261, - 0x00ca18f677300ef3, 0x00e8bb0a827d8548)}, - }}, {{ - {FIELD_LITERAL(0x00df76b3328ada72, 0x002e20621604a7c2, - 0x00f910638a105b09, 0x00ef4724d96ef2cd, - 0x00377d83d6b8a2f7, 0x00b4f48805ade324, - 0x001cd5da8b152018, 0x0045af671a20ca7f)}, - {FIELD_LITERAL(0x009ae3b93a56c404, 0x004a410b7a456699, - 0x00023a619355e6b2, 0x009cdc7297387257, - 0x0055b94d4ae70d04, 0x002cbd607f65b005, - 0x003208b489697166, 0x00ea2aa058867370)}, - {FIELD_LITERAL(0x00f29d2598ee3f32, 0x00b4ac5385d82adc, - 0x007633eaf04df19b, 0x00aa2d3d77ceab01, - 0x004a2302fcbb778a, 0x00927f225d5afa34, - 0x004a8e9d5047f237, 0x008224ae9dbce530)}, - }}, {{ - {FIELD_LITERAL(0x001cf640859b02f8, 0x00758d1d5d5ce427, - 0x00763c784ef4604c, 0x005fa81aee205270, - 0x00ac537bfdfc44cb, 0x004b919bd342d670, - 0x00238508d9bf4b7a, 0x00154888795644f3)}, - {FIELD_LITERAL(0x00c845923c084294, 0x00072419a201bc25, - 0x0045f408b5f8e669, 0x00e9d6a186b74dfe, - 0x00e19108c68fa075, 0x0017b91d874177b7, - 0x002f0ca2c7912c5a, 0x009400aa385a90a2)}, - {FIELD_LITERAL(0x0071110b01482184, 0x00cfed0044f2bef8, - 0x0034f2901cf4662e, 0x003b4ae2a67f9834, - 0x00cca9b96fe94810, 0x00522507ae77abd0, - 0x00bac7422721e73e, 0x0066622b0f3a62b0)}, - }}, {{ - {FIELD_LITERAL(0x00f8ac5cf4705b6a, 0x00867d82dcb457e3, - 0x007e13ab2ccc2ce9, 0x009ee9a018d3930e, - 0x008370f8ecb42df8, 0x002d9f019add263e, - 0x003302385b92d196, 0x00a15654536e2c0c)}, - {FIELD_LITERAL(0x0026ef1614e160af, 0x00c023f9edfc9c76, - 0x00cff090da5f57ba, 0x0076db7a66643ae9, - 0x0019462f8c646999, 0x008fec00b3854b22, - 0x00d55041692a0a1c, 0x0065db894215ca00)}, - {FIELD_LITERAL(0x00a925036e0a451c, 0x002a0390c36b6cc1, - 0x00f27020d90894f4, 0x008d90d52cbd3d7f, - 0x00e1d0137392f3b8, 0x00f017c158b51a8f, - 0x00cac313d3ed7dbc, 0x00b99a81e3eb42d3)}, - }}, {{ - {FIELD_LITERAL(0x00b54850275fe626, 0x0053a3fd1ec71140, - 0x00e3d2d7dbe096fa, 0x00e4ac7b595cce4c, - 0x0077bad449c0a494, 0x00b7c98814afd5b3, - 0x0057226f58486cf9, 0x00b1557154f0cc57)}, - {FIELD_LITERAL(0x008cc9cd236315c0, 0x0031d9c5b39fda54, - 0x00a5713ef37e1171, 0x00293d5ae2886325, - 0x00c4aba3e05015e1, 0x0003f35ef78e4fc6, - 0x0039d6bd3ac1527b, 0x0019d7c3afb77106)}, - {FIELD_LITERAL(0x007b162931a985af, 0x00ad40a2e0daa713, - 0x006df27c4009f118, 0x00503e9f4e2e8bec, - 0x00751a77c82c182d, 0x000298937769245b, - 0x00ffb1e8fabf9ee5, 0x0008334706e09abe)}, - }}, {{ - {FIELD_LITERAL(0x00dbca4e98a7dcd9, 0x00ee29cfc78bde99, - 0x00e4a3b6995f52e9, 0x0045d70189ae8096, - 0x00fd2a8a3b9b0d1b, 0x00af1793b107d8e1, - 0x00dbf92cbe4afa20, 0x00da60f798e3681d)}, - {FIELD_LITERAL(0x004246bfcecc627a, 0x004ba431246c03a4, - 0x00bd1d101872d497, 0x003b73d3f185ee16, - 0x001feb2e2678c0e3, 0x00ff13c5a89dec76, - 0x00ed06042e771d8f, 0x00a4fd2a897a83dd)}, - {FIELD_LITERAL(0x009a4a3be50d6597, 0x00de3165fc5a1096, - 0x004f3f56e345b0c7, 0x00f7bf721d5ab8bc, - 0x004313e47b098c50, 0x00e4c7d5c0e1adbb, - 0x002e3e3db365051e, 0x00a480c2cd6a96fb)}, - }}, {{ - {FIELD_LITERAL(0x00417fa30a7119ed, 0x00af257758419751, - 0x00d358a487b463d4, 0x0089703cc720b00d, - 0x00ce56314ff7f271, 0x0064db171ade62c1, - 0x00640b36d4a22fed, 0x00424eb88696d23f)}, - {FIELD_LITERAL(0x004ede34af2813f3, 0x00d4a8e11c9e8216, - 0x004796d5041de8a5, 0x00c4c6b4d21cc987, - 0x00e8a433ee07fa1e, 0x0055720b5abcc5a1, - 0x008873ea9c74b080, 0x005b3fec1ab65d48)}, - {FIELD_LITERAL(0x0047e5277db70ec5, 0x000a096c66db7d6b, - 0x00b4164cc1730159, 0x004a9f783fe720fe, - 0x00a8177b94449dbc, 0x0095a24ff49a599f, - 0x0069c1c578250cbc, 0x00452019213debf4)}, - }}, {{ - {FIELD_LITERAL(0x0021ce99e09ebda3, 0x00fcbd9f91875ad0, - 0x009bbf6b7b7a0b5f, 0x00388886a69b1940, - 0x00926a56d0f81f12, 0x00e12903c3358d46, - 0x005dfce4e8e1ce9d, 0x0044cfa94e2f7e23)}, - {FIELD_LITERAL(0x001bd59c09e982ea, 0x00f72daeb937b289, - 0x0018b76dca908e0e, 0x00edb498512384ad, - 0x00ce0243b6cc9538, 0x00f96ff690cb4e70, - 0x007c77bf9f673c8d, 0x005bf704c088a528)}, - {FIELD_LITERAL(0x0093d4628dcb33be, 0x0095263d51d42582, - 0x0049b3222458fe06, 0x00e7fce73b653a7f, - 0x003ca2ebce60b369, 0x00c5de239a32bea4, - 0x0063b8b3d71fb6bf, 0x0039aeeb78a1a839)}, - }}, {{ - {FIELD_LITERAL(0x007dc52da400336c, 0x001fded1e15b9457, - 0x00902e00f5568e3a, 0x00219bef40456d2d, - 0x005684161fb3dbc9, 0x004a4e9be49a76ea, - 0x006e685ae88b78ff, 0x0021c42f13042d3c)}, - {FIELD_LITERAL(0x00fb22bb5fd3ce50, 0x0017b48aada7ae54, - 0x00fd5c44ad19a536, 0x000ccc4e4e55e45c, - 0x00fd637d45b4c3f5, 0x0038914e023c37cf, - 0x00ac1881d6a8d898, 0x00611ed8d3d943a8)}, - {FIELD_LITERAL(0x0056e2259d113d2b, 0x00594819b284ec16, - 0x00c7bf794bb36696, 0x00721ee75097cdc6, - 0x00f71be9047a2892, 0x00df6ba142564edf, - 0x0069580b7a184e8d, 0x00f056e38fca0fee)}, - }}, {{ - {FIELD_LITERAL(0x009df98566a18c6d, 0x00cf3a200968f219, - 0x0044ba60da6d9086, 0x00dbc9c0e344da03, - 0x000f9401c4466855, 0x00d46a57c5b0a8d1, - 0x00875a635d7ac7c6, 0x00ef4a933b7e0ae6)}, - {FIELD_LITERAL(0x005e8694077a1535, 0x008bef75f71c8f1d, - 0x000a7c1316423511, 0x00906e1d70604320, - 0x003fc46c1a2ffbd6, 0x00d1d5022e68f360, - 0x002515fba37bbf46, 0x00ca16234e023b44)}, - {FIELD_LITERAL(0x00787c99561f4690, 0x00a857a8c1561f27, - 0x00a10df9223c09fe, 0x00b98a9562e3b154, - 0x004330b8744c3ed2, 0x00e06812807ec5c4, - 0x00e4cf6a7db9f1e3, 0x00d95b089f132a34)}, - }}, {{ - {FIELD_LITERAL(0x002922b39ca33eec, 0x0090d12a5f3ab194, - 0x00ab60c02fb5f8ed, 0x00188d292abba1cf, - 0x00e10edec9698f6e, 0x0069a4d9934133c8, - 0x0024aac40e6d3d06, 0x001702c2177661b0)}, - {FIELD_LITERAL(0x00139078397030bd, 0x000e3c447e859a00, - 0x0064a5b334c82393, 0x00b8aabeb7358093, - 0x00020778bb9ae73b, 0x0032ee94c7892a18, - 0x008215253cb41bda, 0x005e2797593517ae)}, - {FIELD_LITERAL(0x0083765a5f855d4a, 0x0051b6d1351b8ee2, - 0x00116de548b0f7bb, 0x0087bd88703affa0, - 0x0095b2cc34d7fdd2, 0x0084cd81b53f0bc8, - 0x008562fc995350ed, 0x00a39abb193651e3)}, - }}, {{ - {FIELD_LITERAL(0x0019e23f0474b114, 0x00eb94c2ad3b437e, - 0x006ddb34683b75ac, 0x00391f9209b564c6, - 0x00083b3bb3bff7aa, 0x00eedcd0f6dceefc, - 0x00b50817f794fe01, 0x0036474deaaa75c9)}, - {FIELD_LITERAL(0x0091868594265aa2, 0x00797accae98ca6d, - 0x0008d8c5f0f8a184, 0x00d1f4f1c2b2fe6e, - 0x0036783dfb48a006, 0x008c165120503527, - 0x0025fd780058ce9b, 0x0068beb007be7d27)}, - {FIELD_LITERAL(0x00d0ff88aa7c90c2, 0x00b2c60dacf53394, - 0x0094a7284d9666d6, 0x00bed9022ce7a19d, - 0x00c51553f0cd7682, 0x00c3fb870b124992, - 0x008d0bc539956c9b, 0x00fc8cf258bb8885)}, - }}, {{ - {FIELD_LITERAL(0x003667bf998406f8, 0x0000115c43a12975, - 0x001e662f3b20e8fd, 0x0019ffa534cb24eb, - 0x00016be0dc8efb45, 0x00ff76a8b26243f5, - 0x00ae20d241a541e3, 0x0069bd6af13cd430)}, - {FIELD_LITERAL(0x0045fdc16487cda3, 0x00b2d8e844cf2ed7, - 0x00612c50e88c1607, 0x00a08aabc66c1672, - 0x006031fdcbb24d97, 0x001b639525744b93, - 0x004409d62639ab17, 0x00a1853d0347ab1d)}, - {FIELD_LITERAL(0x0075a1a56ebf5c21, 0x00a3e72be9ac53ed, - 0x00efcde1629170c2, 0x0004225fe91ef535, - 0x0088049fc73dfda7, 0x004abc74857e1288, - 0x0024e2434657317c, 0x00d98cb3d3e5543c)}, - }}, {{ - {FIELD_LITERAL(0x00b4b53eab6bdb19, 0x009b22d8b43711d0, - 0x00d948b9d961785d, 0x00cb167b6f279ead, - 0x00191de3a678e1c9, 0x00d9dd9511095c2e, - 0x00f284324cd43067, 0x00ed74fa535151dd)}, - {FIELD_LITERAL(0x007e32c049b5c477, 0x009d2bfdbd9bcfd8, - 0x00636e93045938c6, 0x007fde4af7687298, - 0x0046a5184fafa5d3, 0x0079b1e7f13a359b, - 0x00875adf1fb927d6, 0x00333e21c61bcad2)}, - {FIELD_LITERAL(0x00048014f73d8b8d, 0x0075684aa0966388, - 0x0092be7df06dc47c, 0x0097cebcd0f5568a, - 0x005a7004d9c4c6a9, 0x00b0ecbb659924c7, - 0x00d90332dd492a7c, 0x0057fc14df11493d)}, - }}, {{ - {FIELD_LITERAL(0x0008ed8ea0ad95be, 0x0041d324b9709645, - 0x00e25412257a19b4, 0x0058df9f3423d8d2, - 0x00a9ab20def71304, 0x009ae0dbf8ac4a81, - 0x00c9565977e4392a, 0x003c9269444baf55)}, - {FIELD_LITERAL(0x007df6cbb926830b, 0x00d336058ae37865, - 0x007af47dac696423, 0x0048d3011ec64ac8, - 0x006b87666e40049f, 0x0036a2e0e51303d7, - 0x00ba319bd79dbc55, 0x003e2737ecc94f53)}, - {FIELD_LITERAL(0x00d296ff726272d9, 0x00f6d097928fcf57, - 0x00e0e616a55d7013, 0x00deaf454ed9eac7, - 0x0073a56bedef4d92, 0x006ccfdf6fc92e19, - 0x009d1ee1371a7218, 0x00ee3c2ee4462d80)}, - }}, {{ - {FIELD_LITERAL(0x00437bce9bccdf9d, 0x00e0c8e2f85dc0a3, - 0x00c91a7073995a19, 0x00856ec9fe294559, - 0x009e4b33394b156e, 0x00e245b0dc497e5c, - 0x006a54e687eeaeff, 0x00f1cd1cd00fdb7c)}, - {FIELD_LITERAL(0x008132ae5c5d8cd1, 0x00121d68324a1d9f, - 0x00d6be9dafcb8c76, 0x00684d9070edf745, - 0x00519fbc96d7448e, 0x00388182fdc1f27e, - 0x000235baed41f158, 0x00bf6cf6f1a1796a)}, - {FIELD_LITERAL(0x002adc4b4d148219, 0x003084ada0d3a90a, - 0x0046de8aab0f2e4e, 0x00452d342a67b5fd, - 0x00d4b50f01d4de21, 0x00db6d9fc0cefb79, - 0x008c184c86a462cd, 0x00e17c83764d42da)}, - }}, {{ - {FIELD_LITERAL(0x007b2743b9a1e01a, 0x007847ffd42688c4, - 0x006c7844d610a316, 0x00f0cb8b250aa4b0, - 0x00a19060143b3ae6, 0x0014eb10b77cfd80, - 0x000170905729dd06, 0x00063b5b9cd72477)}, - {FIELD_LITERAL(0x00ce382dc7993d92, 0x00021153e938b4c8, - 0x00096f7567f48f51, 0x0058f81ddfe4b0d5, - 0x00cc379a56b355c7, 0x002c760770d3e819, - 0x00ee22d1d26e5a40, 0x00de6d93d5b082d7)}, - {FIELD_LITERAL(0x000a91a42c52e056, 0x00185f6b77fce7ea, - 0x000803c51962f6b5, 0x0022528582ba563d, - 0x0043f8040e9856d6, 0x0085a29ec81fb860, - 0x005f9a611549f5ff, 0x00c1f974ecbd4b06)}, - }}, {{ - {FIELD_LITERAL(0x005b64c6fd65ec97, 0x00c1fdd7f877bc7f, - 0x000d9cc6c89f841c, 0x005c97b7f1aff9ad, - 0x0075e3c61475d47e, 0x001ecb1ba8153011, - 0x00fe7f1c8d71d40d, 0x003fa9757a229832)}, - {FIELD_LITERAL(0x00ffc5c89d2b0cba, 0x00d363d42e3e6fc3, - 0x0019a1a0118e2e8a, 0x00f7baeff48882e1, - 0x001bd5af28c6b514, 0x0055476ca2253cb2, - 0x00d8eb1977e2ddf3, 0x00b173b1adb228a1)}, - {FIELD_LITERAL(0x00f2cb99dd0ad707, 0x00e1e08b6859ddd8, - 0x000008f2d0650bcc, 0x00d7ed392f8615c3, - 0x00976750a94da27f, 0x003e83bb0ecb69ba, - 0x00df8e8d15c14ac6, 0x00f9f7174295d9c2)}, - }}, {{ - {FIELD_LITERAL(0x00f11cc8e0e70bcb, 0x00e5dc689974e7dd, - 0x0014e409f9ee5870, 0x00826e6689acbd63, - 0x008a6f4e3d895d88, 0x00b26a8da41fd4ad, - 0x000fb7723f83efd7, 0x009c749db0a5f6c3)}, - {FIELD_LITERAL(0x002389319450f9ba, 0x003677f31aa1250a, - 0x0092c3db642f38cb, 0x00f8b64c0dfc9773, - 0x00cd49fe3505b795, 0x0068105a4090a510, - 0x00df0ba2072a8bb6, 0x00eb396143afd8be)}, - {FIELD_LITERAL(0x00a0d4ecfb24cdff, 0x00ddaf8008ba6479, - 0x00f0b3e36d4b0f44, 0x003734bd3af1f146, - 0x00b87e2efc75527e, 0x00d230df55ddab50, - 0x002613257ae56c1d, 0x00bc0946d135934d)}, - }}, {{ - {FIELD_LITERAL(0x00468711bd994651, 0x0033108fa67561bf, - 0x0089d760192a54b4, 0x00adc433de9f1871, - 0x000467d05f36e050, 0x007847e0f0579f7f, - 0x00a2314ad320052d, 0x00b3a93649f0b243)}, - {FIELD_LITERAL(0x0067f8f0c4fe26c9, 0x0079c4a3cc8f67b9, - 0x0082b1e62f23550d, 0x00f2d409caefd7f5, - 0x0080e67dcdb26e81, 0x0087ae993ea1f98a, - 0x00aa108becf61d03, 0x001acf11efb608a3)}, - {FIELD_LITERAL(0x008225febbab50d9, 0x00f3b605e4dd2083, - 0x00a32b28189e23d2, 0x00d507e5e5eb4c97, - 0x005a1a84e302821f, 0x0006f54c1c5f08c7, - 0x00a347c8cb2843f0, 0x0009f73e9544bfa5)}, - }}, {{ - {FIELD_LITERAL(0x006c59c9ae744185, 0x009fc32f1b4282cd, - 0x004d6348ca59b1ac, 0x00105376881be067, - 0x00af4096013147dc, 0x004abfb5a5cb3124, - 0x000d2a7f8626c354, 0x009c6ed568e07431)}, - {FIELD_LITERAL(0x00e828333c297f8b, 0x009ef3cf8c3f7e1f, - 0x00ab45f8fff31cb9, 0x00c8b4178cb0b013, - 0x00d0c50dd3260a3f, 0x0097126ac257f5bc, - 0x0042376cc90c705a, 0x001d96fdb4a1071e)}, - {FIELD_LITERAL(0x00542d44d89ee1a8, 0x00306642e0442d98, - 0x0090853872b87338, 0x002362cbf22dc044, - 0x002c222adff663b8, 0x0067c924495fcb79, - 0x000e621d983c977c, 0x00df77a9eccb66fb)}, - }}, {{ - {FIELD_LITERAL(0x002809e4bbf1814a, 0x00b9e854f9fafb32, - 0x00d35e67c10f7a67, 0x008f1bcb76e748cf, - 0x004224d9515687d2, 0x005ba0b774e620c4, - 0x00b5e57db5d54119, 0x00e15babe5683282)}, - {FIELD_LITERAL(0x00832d02369b482c, 0x00cba52ff0d93450, - 0x003fa9c908d554db, 0x008d1e357b54122f, - 0x00abd91c2dc950c6, 0x007eff1df4c0ec69, - 0x003f6aeb13fb2d31, 0x00002d6179fc5b2c)}, - {FIELD_LITERAL(0x0046c9eda81c9c89, 0x00b60cb71c8f62fc, - 0x0022f5a683baa558, 0x00f87319fccdf997, - 0x009ca09b51ce6a22, 0x005b12baf4af7d77, - 0x008a46524a1e33e2, 0x00035a77e988be0d)}, - }}, {{ - {FIELD_LITERAL(0x00a7efe46a7dbe2f, 0x002f66fd55014fe7, - 0x006a428afa1ff026, 0x0056caaa9604ab72, - 0x0033f3bcd7fac8ae, 0x00ccb1aa01c86764, - 0x00158d1edf13bf40, 0x009848ee76fcf3b4)}, - {FIELD_LITERAL(0x00a9e7730a819691, 0x00d9cc73c4992b70, - 0x00e299bde067de5a, 0x008c314eb705192a, - 0x00e7226f17e8a3cc, 0x0029dfd956e65a47, - 0x0053a8e839073b12, 0x006f942b2ab1597e)}, - {FIELD_LITERAL(0x001c3d780ecd5e39, 0x0094f247fbdcc5fe, - 0x00d5c786fd527764, 0x00b6f4da74f0db2a, - 0x0080f1f8badcd5fc, 0x00f36a373ad2e23b, - 0x00f804f9f4343bf2, 0x00d1af40ec623982)}, - }}, {{ - {FIELD_LITERAL(0x0082aeace5f1b144, 0x00f68b3108cf4dd3, - 0x00634af01dde3020, 0x000beab5df5c2355, - 0x00e8b790d1b49b0b, 0x00e48d15854e36f4, - 0x0040ab2d95f3db9f, 0x002711c4ed9e899a)}, - {FIELD_LITERAL(0x0039343746531ebe, 0x00c8509d835d429d, - 0x00e79eceff6b0018, 0x004abfd31e8efce5, - 0x007bbfaaa1e20210, 0x00e3be89c193e179, - 0x001c420f4c31d585, 0x00f414a315bef5ae)}, - {FIELD_LITERAL(0x007c296a24990df8, 0x00d5d07525a75588, - 0x00dd8e113e94b7e7, 0x007bbc58febe0cc8, - 0x0029f51af9bfcad3, 0x007e9311ec7ab6f3, - 0x009a884de1676343, 0x0050d5f2dce84be9)}, - }}, {{ - {FIELD_LITERAL(0x005fa020cca2450a, 0x00491c29db6416d8, - 0x0037cefe3f9f9a85, 0x003d405230647066, - 0x0049e835f0fdbe89, 0x00feb78ac1a0815c, - 0x00828e4b32dc9724, 0x00db84f2dc8d6fd4)}, - {FIELD_LITERAL(0x0098cddc8b39549a, 0x006da37e3b05d22c, - 0x00ce633cfd4eb3cb, 0x00fda288ef526acd, - 0x0025338878c5d30a, 0x00f34438c4e5a1b4, - 0x00584efea7c310f1, 0x0041a551f1b660ad)}, - {FIELD_LITERAL(0x00d7f7a8fbd6437a, 0x0062872413bf3753, - 0x00ad4bbcb43c584b, 0x007fe49be601d7e3, - 0x0077c659789babf4, 0x00eb45fcb06a741b, - 0x005ce244913f9708, 0x0088426401736326)}, - }}, {{ - {FIELD_LITERAL(0x007bf562ca768d7c, 0x006c1f3a174e387c, - 0x00f024b447fee939, 0x007e7af75f01143f, - 0x003adb70b4eed89d, 0x00e43544021ad79a, - 0x0091f7f7042011f6, 0x0093c1a1ee3a0ddc)}, - {FIELD_LITERAL(0x00a0b68ec1eb72d2, 0x002c03235c0d45a0, - 0x00553627323fe8c5, 0x006186e94b17af94, - 0x00a9906196e29f14, 0x0025b3aee6567733, - 0x007e0dd840080517, 0x0018eb5801a4ba93)}, - {FIELD_LITERAL(0x00d7fe7017bf6a40, 0x006e3f0624be0c42, - 0x00ffbba205358245, 0x00f9fc2cf8194239, - 0x008d93b37bf15b4e, 0x006ddf2e38be8e95, - 0x002b6e79bf5fcff9, 0x00ab355da425e2de)}, - }}, {{ - {FIELD_LITERAL(0x00938f97e20be973, 0x0099141a36aaf306, - 0x0057b0ca29e545a1, 0x0085db571f9fbc13, - 0x008b333c554b4693, 0x0043ab6ef3e241cb, - 0x0054fb20aa1e5c70, 0x00be0ff852760adf)}, - {FIELD_LITERAL(0x003973d8938971d6, 0x002aca26fa80c1f5, - 0x00108af1faa6b513, 0x00daae275d7924e6, - 0x0053634ced721308, 0x00d2355fe0bbd443, - 0x00357612b2d22095, 0x00f9bb9dd4136cf3)}, - {FIELD_LITERAL(0x002bff12cf5e03a5, 0x001bdb1fa8a19cf8, - 0x00c91c6793f84d39, 0x00f869f1b2eba9af, - 0x0059bc547dc3236b, 0x00d91611d6d38689, - 0x00e062daaa2c0214, 0x00ed3c047cc2bc82)}, - }}, {{ - {FIELD_LITERAL(0x000050d70c32b31a, 0x001939d576d437b3, - 0x00d709e598bf9fe6, 0x00a885b34bd2ee9e, - 0x00dd4b5c08ab1a50, 0x0091bebd50b55639, - 0x00cf79ff64acdbc6, 0x006067a39d826336)}, - {FIELD_LITERAL(0x0062dd0fb31be374, 0x00fcc96b84c8e727, - 0x003f64f1375e6ae3, 0x0057d9b6dd1af004, - 0x00d6a167b1103c7b, 0x00dd28f3180fb537, - 0x004ff27ad7167128, 0x008934c33461f2ac)}, - {FIELD_LITERAL(0x0065b472b7900043, 0x00ba7efd2ff1064b, - 0x000b67d6c4c3020f, 0x0012d28469f4e46d, - 0x0031c32939703ec7, 0x00b49f0bce133066, - 0x00f7e10416181d47, 0x005c90f51867eecc)}, - }}, {{ - {FIELD_LITERAL(0x0051207abd179101, 0x00fc2a5c20d9c5da, - 0x00fb9d5f2701b6df, 0x002dd040fdea82b8, - 0x00f163b0738442ff, 0x00d9736bd68855b8, - 0x00e0d8e93005e61c, 0x00df5a40b3988570)}, - {FIELD_LITERAL(0x0006918f5dfce6dc, 0x00d4bf1c793c57fb, - 0x0069a3f649435364, 0x00e89a50e5b0cd6e, - 0x00b9f6a237e973af, 0x006d4ed8b104e41d, - 0x00498946a3924cd2, 0x00c136ec5ac9d4f7)}, - {FIELD_LITERAL(0x0011a9c290ac5336, 0x002b9a2d4a6a6533, - 0x009a8a68c445d937, 0x00361b27b07e5e5c, - 0x003c043b1755b974, 0x00b7eb66cf1155ee, - 0x0077af5909eefff2, 0x0098f609877cc806)}, - }}, {{ - {FIELD_LITERAL(0x00ab13af436bf8f4, 0x000bcf0a0dac8574, - 0x00d50c864f705045, 0x00c40e611debc842, - 0x0085010489bd5caa, 0x007c5050acec026f, - 0x00f67d943c8da6d1, 0x00de1da0278074c6)}, - {FIELD_LITERAL(0x00b373076597455f, 0x00e83f1af53ac0f5, - 0x0041f63c01dc6840, 0x0097dea19b0c6f4b, - 0x007f9d63b4c1572c, 0x00e692d492d0f5f0, - 0x00cbcb392e83b4ad, 0x0069c0f39ed9b1a8)}, - {FIELD_LITERAL(0x00861030012707c9, 0x009fbbdc7fd4aafb, - 0x008f591d6b554822, 0x00df08a41ea18ade, - 0x009d7d83e642abea, 0x0098c71bda3b78ff, - 0x0022c89e7021f005, 0x0044d29a3fe1e3c4)}, - }}, {{ - {FIELD_LITERAL(0x00e748cd7b5c52f2, 0x00ea9df883f89cc3, - 0x0018970df156b6c7, 0x00c5a46c2a33a847, - 0x00cbde395e32aa09, 0x0072474ebb423140, - 0x00fb00053086a23d, 0x001dafcfe22d4e1f)}, - {FIELD_LITERAL(0x00c903ee6d825540, 0x00add6c4cf98473e, - 0x007636efed4227f1, 0x00905124ae55e772, - 0x00e6b38fab12ed53, 0x0045e132b863fe55, - 0x003974662edb366a, 0x00b1787052be8208)}, - {FIELD_LITERAL(0x00a614b00d775c7c, 0x00d7c78941cc7754, - 0x00422dd68b5dabc4, 0x00a6110f0167d28b, - 0x00685a309c252886, 0x00b439ffd5143660, - 0x003656e29ee7396f, 0x00c7c9b9ed5ad854)}, - }}, {{ - {FIELD_LITERAL(0x0040f7e7c5b37bf2, 0x0064e4dc81181bba, - 0x00a8767ae2a366b6, 0x001496b4f90546f2, - 0x002a28493f860441, 0x0021f59513049a3a, - 0x00852d369a8b7ee3, 0x00dd2e7d8b7d30a9)}, - {FIELD_LITERAL(0x00006e34a35d9fbc, 0x00eee4e48b2f019a, - 0x006b344743003a5f, 0x00541d514f04a7e3, - 0x00e81f9ee7647455, 0x005e2b916c438f81, - 0x00116f8137b7eff0, 0x009bd3decc7039d1)}, - {FIELD_LITERAL(0x0005d226f434110d, 0x00af8288b8ef21d5, - 0x004a7a52ef181c8c, 0x00be0b781b4b06de, - 0x00e6e3627ded07e1, 0x00e43aa342272b8b, - 0x00e86ab424577d84, 0x00fb292c566e35bb)}, - }}, {{ - {FIELD_LITERAL(0x00334f5303ea1222, 0x00dfb3dbeb0a5d3e, - 0x002940d9592335c1, 0x00706a7a63e8938a, - 0x005a533558bc4caf, 0x00558e33192022a9, - 0x00970d9faf74c133, 0x002979fcb63493ca)}, - {FIELD_LITERAL(0x00e38abece3c82ab, 0x005a51f18a2c7a86, - 0x009dafa2e86d592e, 0x00495a62eb688678, - 0x00b79df74c0eb212, 0x0023e8cc78b75982, - 0x005998cb91075e13, 0x00735aa9ba61bc76)}, - {FIELD_LITERAL(0x00d9f7a82ddbe628, 0x00a1fc782889ae0f, - 0x0071ffda12d14b66, 0x0037cf4eca7fb3d5, - 0x00c80bc242c58808, 0x0075bf8c2d08c863, - 0x008d41f31afc52a7, 0x00197962ecf38741)}, - }}, {{ - {FIELD_LITERAL(0x006e9f475cccf2ee, 0x00454b9cd506430c, - 0x00224a4fb79ee479, 0x0062e3347ef0b5e2, - 0x0034fd2a3512232a, 0x00b8b3cb0f457046, - 0x00eb20165daa38ec, 0x00128eebc2d9c0f7)}, - {FIELD_LITERAL(0x00bfc5fa1e4ea21f, 0x00c21d7b6bb892e6, - 0x00cf043f3acf0291, 0x00c13f2f849b3c90, - 0x00d1a97ebef10891, 0x0061e130a445e7fe, - 0x0019513fdedbf22b, 0x001d60c813bff841)}, - {FIELD_LITERAL(0x0019561c7fcf0213, 0x00e3dca6843ebd77, - 0x0068ea95b9ca920e, 0x009bdfb70f253595, - 0x00c68f59186aa02a, 0x005aee1cca1c3039, - 0x00ab79a8a937a1ce, 0x00b9a0e549959e6f)}, - }}, {{ - {FIELD_LITERAL(0x00c79e0b6d97dfbd, 0x00917c71fd2bc6e8, - 0x00db7529ccfb63d8, 0x00be5be957f17866, - 0x00a9e11fdc2cdac1, 0x007b91a8e1f44443, - 0x00a3065e4057d80f, 0x004825f5b8d5f6d4)}, - {FIELD_LITERAL(0x003e4964fa8a8fc8, 0x00f6a1cdbcf41689, - 0x00943cb18fe7fda7, 0x00606dafbf34440a, - 0x005d37a86399c789, 0x00e79a2a69417403, - 0x00fe34f7e68b8866, 0x0011f448ed2df10e)}, - {FIELD_LITERAL(0x00f1f57efcc1fcc4, 0x00513679117de154, - 0x002e5b5b7c86d8c3, 0x009f6486561f9cfb, - 0x00169e74b0170cf7, 0x00900205af4af696, - 0x006acfddb77853f3, 0x00df184c90f31068)}, - }}, {{ - {FIELD_LITERAL(0x00b37396c3320791, 0x00fc7b67175c5783, - 0x00c36d2cd73ecc38, 0x0080ebcc0b328fc5, - 0x0043a5b22b35d35d, 0x00466c9f1713c9da, - 0x0026ad346dcaa8da, 0x007c684e701183a6)}, - {FIELD_LITERAL(0x00fd579ffb691713, 0x00b76af4f81c412d, - 0x00f239de96110f82, 0x00e965fb437f0306, - 0x00ca7e9436900921, 0x00e487f1325fa24a, - 0x00633907de476380, 0x00721c62ac5b8ea0)}, - {FIELD_LITERAL(0x00c0d54e542eb4f9, 0x004ed657171c8dcf, - 0x00b743a4f7c2a39b, 0x00fd9f93ed6cc567, - 0x00307fae3113e58b, 0x0058aa577c93c319, - 0x00d254556f35b346, 0x00491aada2203f0d)}, - }}, {{ - {FIELD_LITERAL(0x00dff3103786ff34, 0x000144553b1f20c3, - 0x0095613baeb930e4, 0x00098058275ea5d4, - 0x007cd1402b046756, 0x0074d74e4d58aee3, - 0x005f93fc343ff69b, 0x00873df17296b3b0)}, - {FIELD_LITERAL(0x00c4a1fb48635413, 0x00b5dd54423ad59f, - 0x009ff5d53fd24a88, 0x003c98d267fc06a7, - 0x002db7cb20013641, 0x00bd1d6716e191f2, - 0x006dbc8b29094241, 0x0044bbf233dafa2c)}, - {FIELD_LITERAL(0x0055838d41f531e6, 0x00bf6a2dd03c81b2, - 0x005827a061c4839e, 0x0000de2cbb36aac3, - 0x002efa29d9717478, 0x00f9e928cc8a77ba, - 0x00c134b458def9ef, 0x00958a182223fc48)}, - }}, {{ - {FIELD_LITERAL(0x000a9ee23c06881f, 0x002c727d3d871945, - 0x00f47d971512d24a, 0x00671e816f9ef31a, - 0x00883af2cfaad673, 0x00601f98583d6c9a, - 0x00b435f5adc79655, 0x00ad87b71c04bff2)}, - {FIELD_LITERAL(0x007860d99db787cf, 0x00fda8983018f4a8, - 0x008c8866bac4743c, 0x00ef471f84c82a3f, - 0x00abea5976d3b8e7, 0x00714882896cd015, - 0x00b49fae584ddac5, 0x008e33a1a0b69c81)}, - {FIELD_LITERAL(0x007b6ee2c9e8a9ec, 0x002455dbbd89d622, - 0x006490cf4eaab038, 0x00d925f6c3081561, - 0x00153b3047de7382, 0x003b421f8bdceb6f, - 0x00761a4a5049da78, 0x00980348c5202433)}, - }}, {{ - {FIELD_LITERAL(0x007f8a43da97dd5c, 0x00058539c800fc7b, - 0x0040f3cf5a28414a, 0x00d68dd0d95283d6, - 0x004adce9da90146e, 0x00befa41c7d4f908, - 0x007603bc2e3c3060, 0x00bdf360ab3545db)}, - {FIELD_LITERAL(0x00eebfd4e2312cc3, 0x00474b2564e4fc8c, - 0x003303ef14b1da9b, 0x003c93e0e66beb1d, - 0x0013619b0566925a, 0x008817c24d901bf3, - 0x00b62bd8898d218b, 0x0075a7716f1e88a2)}, - {FIELD_LITERAL(0x0009218da1e6890f, 0x0026907f5fd02575, - 0x004dabed5f19d605, 0x003abf181870249d, - 0x00b52fd048cc92c4, 0x00b6dd51e415a5c5, - 0x00d9eb82bd2b4014, 0x002c865a43b46b43)}, - }}, {{ - {FIELD_LITERAL(0x0070047189452f4c, 0x00f7ad12e1ce78d5, - 0x00af1ba51ec44a8b, 0x005f39f63e667cd6, - 0x00058eac4648425e, 0x00d7fdab42bea03b, - 0x0028576a5688de15, 0x00af973209e77c10)}, - {FIELD_LITERAL(0x00c338b915d8fef0, 0x00a893292045c39a, - 0x0028ab4f2eba6887, 0x0060743cb519fd61, - 0x0006213964093ac0, 0x007c0b7a43f6266d, - 0x008e3557c4fa5bda, 0x002da976de7b8d9d)}, - {FIELD_LITERAL(0x0048729f8a8b6dcd, 0x00fe23b85cc4d323, - 0x00e7384d16e4db0e, 0x004a423970678942, - 0x00ec0b763345d4ba, 0x00c477b9f99ed721, - 0x00c29dad3777b230, 0x001c517b466f7df6)}, - }}, {{ - {FIELD_LITERAL(0x006366c380f7b574, 0x001c7d1f09ff0438, - 0x003e20a7301f5b22, 0x00d3efb1916d28f6, - 0x0049f4f81060ce83, 0x00c69d91ea43ced1, - 0x002b6f3e5cd269ed, 0x005b0fb22ce9ec65)}, - {FIELD_LITERAL(0x00aa2261022d883f, 0x00ebcca4548010ac, - 0x002528512e28a437, 0x0070ca7676b66082, - 0x0084bda170f7c6d3, 0x00581b4747c9b8bb, - 0x005c96a01061c7e2, 0x00fb7c4a362b5273)}, - {FIELD_LITERAL(0x00c30020eb512d02, 0x0060f288283a4d26, - 0x00b7ed13becde260, 0x0075ebb74220f6e9, - 0x00701079fcfe8a1f, 0x001c28fcdff58938, - 0x002e4544b8f4df6b, 0x0060c5bc4f1a7d73)}, - }}, {{ - {FIELD_LITERAL(0x00ae307cf069f701, 0x005859f222dd618b, - 0x00212d6c46ec0b0d, 0x00a0fe4642afb62d, - 0x00420d8e4a0a8903, 0x00a80ff639bdf7b0, - 0x0019bee1490b5d8e, 0x007439e4b9c27a86)}, - {FIELD_LITERAL(0x00a94700032a093f, 0x0076e96c225216e7, - 0x00a63a4316e45f91, 0x007d8bbb4645d3b2, - 0x00340a6ff22793eb, 0x006f935d4572aeb7, - 0x00b1fb69f00afa28, 0x009e8f3423161ed3)}, - {FIELD_LITERAL(0x009ef49c6b5ced17, 0x00a555e6269e9f0a, - 0x007e6f1d79ec73b5, 0x009ac78695a32ac4, - 0x0001d77fbbcd5682, 0x008cea1fee0aaeed, - 0x00f42bea82a53462, 0x002e46ab96cafcc9)}, - }}, {{ - {FIELD_LITERAL(0x0051cfcc5885377a, 0x00dce566cb1803ca, - 0x00430c7643f2c7d4, 0x00dce1a1337bdcc0, - 0x0010d5bd7283c128, 0x003b1b547f9b46fe, - 0x000f245e37e770ab, 0x007b72511f022b37)}, - {FIELD_LITERAL(0x0060db815bc4786c, 0x006fab25beedc434, - 0x00c610d06084797c, 0x000c48f08537bec0, - 0x0031aba51c5b93da, 0x007968fa6e01f347, - 0x0030070da52840c6, 0x00c043c225a4837f)}, - {FIELD_LITERAL(0x001bcfd00649ee93, 0x006dceb47e2a0fd5, - 0x00f2cebda0cf8fd0, 0x00b6b9d9d1fbdec3, - 0x00815262e6490611, 0x00ef7f5ce3176760, - 0x00e49cd0c998d58b, 0x005fc6cc269ba57c)}, - }}, {{ - {FIELD_LITERAL(0x008940211aa0d633, 0x00addae28136571d, - 0x00d68fdbba20d673, 0x003bc6129bc9e21a, - 0x000346cf184ebe9a, 0x0068774d741ebc7f, - 0x0019d5e9e6966557, 0x0003cbd7f981b651)}, - {FIELD_LITERAL(0x004a2902926f8d3f, 0x00ad79b42637ab75, - 0x0088f60b90f2d4e8, 0x0030f54ef0e398c4, - 0x00021dc9bf99681e, 0x007ebf66fde74ee3, - 0x004ade654386e9a4, 0x00e7485066be4c27)}, - {FIELD_LITERAL(0x00445f1263983be0, 0x004cf371dda45e6a, - 0x00744a89d5a310e7, 0x001f20ce4f904833, - 0x00e746edebe66e29, 0x000912ab1f6c153d, - 0x00f61d77d9b2444c, 0x0001499cd6647610)}, + {FIELD_LITERAL(0x00cc3b062366f4ccULL, 0x003d6e34e314aa3cULL, + 0x00d51c0a7521774dULL, 0x0094e060eec6ab8bULL, + 0x00d21291b4d80082ULL, 0x00befed12b55ef1eULL, + 0x00c3dd2df5c94518ULL, 0x00e0a7b112b8d4e6ULL)}, + {FIELD_LITERAL(0x0019eb5608d8723aULL, 0x00d1bab52fb3aedbULL, + 0x00270a7311ebc90cULL, 0x0037c12b91be7f13ULL, + 0x005be16cd8b5c704ULL, 0x003e181acda888e1ULL, + 0x00bc1f00fc3fc6d0ULL, 0x00d3839bfa319e20ULL)}, + {FIELD_LITERAL(0x003caeb88611909fULL, 0x00ea8b378c4df3d4ULL, + 0x00b3295b95a5a19aULL, 0x00a65f97514bdfb5ULL, + 0x00b39efba743cab1ULL, 0x0016ba98b862fd2dULL, + 0x0001508812ee71d7ULL, 0x000a75740eea114aULL)}, + }}, {{ + {FIELD_LITERAL(0x00ebcf0eb649f823ULL, 0x00166d332e98ea03ULL, + 0x0059ddf64f5cd5f6ULL, 0x0047763123d9471bULL, + 0x00a64065c53ef62fULL, 0x00978e44c480153dULL, + 0x000b5b2a0265f194ULL, 0x0046a24b9f32965aULL)}, + {FIELD_LITERAL(0x00b9eef787034df0ULL, 0x0020bc24de3390cdULL, + 0x000022160bae99bbULL, 0x00ae66e886e97946ULL, + 0x0048d4bbe02cbb8bULL, 0x0072ba97b34e38d4ULL, + 0x00eae7ec8f03e85aULL, 0x005ba92ecf808b2cULL)}, + {FIELD_LITERAL(0x00c9cfbbe74258fdULL, 0x00843a979ea9eaa7ULL, + 0x000cbb4371cfbe90ULL, 0x0059bac8f7f0a628ULL, + 0x004b3dff882ff530ULL, 0x0011869df4d90733ULL, + 0x00595aa71f4abfc2ULL, 0x0070e2d38990c2e6ULL)}, + }}, {{ + {FIELD_LITERAL(0x00de2010c0a01733ULL, 0x00c739a612e24297ULL, + 0x00a7212643141d7cULL, 0x00f88444f6b67c11ULL, + 0x00484b7b16ec28f2ULL, 0x009c1b8856af9c68ULL, + 0x00ff4669591fe9d6ULL, 0x0054974be08a32c8ULL)}, + {FIELD_LITERAL(0x0010de3fd682ceedULL, 0x008c07642d83ca4eULL, + 0x0013bb064e00a1ccULL, 0x009411ae27870e11ULL, + 0x00ea8e5b4d531223ULL, 0x0032fe7d2aaece2eULL, + 0x00d989e243e7bb41ULL, 0x000fe79a508e9b8bULL)}, + {FIELD_LITERAL(0x005e0426b9bfc5b1ULL, 0x0041a5b1d29ee4faULL, + 0x0015b0def7774391ULL, 0x00bc164f1f51af01ULL, + 0x00d543b0942797b9ULL, 0x003c129b6398099cULL, + 0x002b114c6e5adf18ULL, 0x00b4e630e4018a7bULL)}, + }}, {{ + {FIELD_LITERAL(0x00d490afc95f8420ULL, 0x00b096bf50c1d9b9ULL, + 0x00799fd707679866ULL, 0x007c74d9334afbeaULL, + 0x00efaa8be80ff4edULL, 0x0075c4943bb81694ULL, + 0x00c21c2fca161f36ULL, 0x00e77035d492bfeeULL)}, + {FIELD_LITERAL(0x006658a190dd6661ULL, 0x00e0e9bab38609a6ULL, + 0x0028895c802237edULL, 0x006a0229c494f587ULL, + 0x002dcde96c9916b7ULL, 0x00d158822de16218ULL, + 0x00173b917a06856fULL, 0x00ca78a79ae07326ULL)}, + {FIELD_LITERAL(0x00e35bfc79caced4ULL, 0x0087238a3e1fe3bbULL, + 0x00bcbf0ff4ceff5bULL, 0x00a19c1c94099b91ULL, + 0x0071e102b49db976ULL, 0x0059e3d004eada1eULL, + 0x008da78afa58a47eULL, 0x00579c8ebf269187ULL)}, + }}, {{ + {FIELD_LITERAL(0x00a16c2905eee75fULL, 0x009d4bcaea2c7e1dULL, + 0x00d3bd79bfad19dfULL, 0x0050da745193342cULL, + 0x006abdb8f6b29ab1ULL, 0x00a24fe0a4fef7efULL, + 0x0063730da1057dfbULL, 0x00a08c312c8eb108ULL)}, + {FIELD_LITERAL(0x00b583be005375beULL, 0x00a40c8f8a4e3df4ULL, + 0x003fac4a8f5bdbf7ULL, 0x00d4481d872cd718ULL, + 0x004dc8749cdbaefeULL, 0x00cce740d5e5c975ULL, + 0x000b1c1f4241fd21ULL, 0x00a76de1b4e1cd07ULL)}, + {FIELD_LITERAL(0x007a076500d30b62ULL, 0x000a6e117b7f090fULL, + 0x00c8712ae7eebd9aULL, 0x000fbd6c1d5f6ff7ULL, + 0x003a7977246ebf11ULL, 0x00166ed969c6600eULL, + 0x00aa42e469c98becULL, 0x00dc58f307cf0666ULL)}, + }}, {{ + {FIELD_LITERAL(0x004b491f65a9a28bULL, 0x006a10309e8a55b7ULL, + 0x00b67210185187efULL, 0x00cf6497b12d9b8fULL, + 0x0085778c56e2b1baULL, 0x0015b4c07a814d85ULL, + 0x00686479e62da561ULL, 0x008de5d88f114916ULL)}, + {FIELD_LITERAL(0x00e37c88d6bba7b1ULL, 0x003e4577e1b8d433ULL, + 0x0050d8ea5f510ec0ULL, 0x0042fc9f2da9ef59ULL, + 0x003bd074c1141420ULL, 0x00561b8b7b68774eULL, + 0x00232e5e5d1013a3ULL, 0x006b7f2cb3d7e73fULL)}, + {FIELD_LITERAL(0x004bdd0f0b41e6a0ULL, 0x001773057c405d24ULL, + 0x006029f99915bd97ULL, 0x006a5ba70a17fe2fULL, + 0x0046111977df7e08ULL, 0x004d8124c89fb6b7ULL, + 0x00580983b2bb2724ULL, 0x00207bf330d6f3feULL)}, + }}, {{ + {FIELD_LITERAL(0x007efdc93972a48bULL, 0x002f5e50e78d5feeULL, + 0x0080dc11d61c7fe5ULL, 0x0065aa598707245bULL, + 0x009abba2300641beULL, 0x000c68787656543aULL, + 0x00ffe0fef2dc0a17ULL, 0x00007ffbd6cb4f3aULL)}, + {FIELD_LITERAL(0x0036012f2b836efcULL, 0x00458c126d6b5fbcULL, + 0x00a34436d719ad1eULL, 0x0097be6167117deaULL, + 0x0009c219c879cff3ULL, 0x0065564493e60755ULL, + 0x00993ac94a8cdec0ULL, 0x002d4885a4d0dbafULL)}, + {FIELD_LITERAL(0x00598b60b4c068baULL, 0x00c547a0be7f1afdULL, + 0x009582164acf12afULL, 0x00af4acac4fbbe40ULL, + 0x005f6ca7c539121aULL, 0x003b6e752ebf9d66ULL, + 0x00f08a30d5cac5d4ULL, 0x00e399bb5f97c5a9ULL)}, + }}, {{ + {FIELD_LITERAL(0x007445a0409c0a66ULL, 0x00a65c369f3829c0ULL, + 0x0031d248a4f74826ULL, 0x006817f34defbe8eULL, + 0x00649741d95ebf2eULL, 0x00d46466ab16b397ULL, + 0x00fdc35703bee414ULL, 0x00343b43334525f8ULL)}, + {FIELD_LITERAL(0x001796bea93f6401ULL, 0x00090c5a42e85269ULL, + 0x00672412ba1252edULL, 0x001201d47b6de7deULL, + 0x006877bccfe66497ULL, 0x00b554fd97a4c161ULL, + 0x009753f42dbac3cfULL, 0x00e983e3e378270aULL)}, + {FIELD_LITERAL(0x00ac3eff18849872ULL, 0x00f0eea3bff05690ULL, + 0x00a6d72c21dd505dULL, 0x001b832642424169ULL, + 0x00a6813017b540e5ULL, 0x00a744bd71b385cdULL, + 0x0022a7d089130a7bULL, 0x004edeec9a133486ULL)}, + }}, {{ + {FIELD_LITERAL(0x00b2d6729196e8a9ULL, 0x0088a9bb2031cef4ULL, + 0x00579e7787dc1567ULL, 0x0030f49feb059190ULL, + 0x00a0b1d69c7f7d8fULL, 0x0040bdcc6d9d806fULL, + 0x00d76c4037edd095ULL, 0x00bbf24376415dd7ULL)}, + {FIELD_LITERAL(0x00240465ff5a7197ULL, 0x00bb97e76caf27d0ULL, + 0x004b4edbf8116d39ULL, 0x001d8586f708cbaaULL, + 0x000f8ee8ff8e4a50ULL, 0x00dde5a1945dd622ULL, + 0x00e6fc1c0957e07cULL, 0x0041c9cdabfd88a0ULL)}, + {FIELD_LITERAL(0x005344b0bf5b548cULL, 0x002957d0b705cc99ULL, + 0x00f586a70390553dULL, 0x0075b3229f583cc3ULL, + 0x00a1aa78227490e4ULL, 0x001bf09cf7957717ULL, + 0x00cf6bf344325f52ULL, 0x0065bd1c23ca3ecfULL)}, + }}, {{ + {FIELD_LITERAL(0x009bff3b3239363cULL, 0x00e17368796ef7c0ULL, + 0x00528b0fe0971f3aULL, 0x0008014fc8d4a095ULL, + 0x00d09f2e8a521ec4ULL, 0x006713ab5dde5987ULL, + 0x0003015758e0dbb1ULL, 0x00215999f1ba212dULL)}, + {FIELD_LITERAL(0x002c88e93527da0eULL, 0x0077c78f3456aad5ULL, + 0x0071087a0a389d1cULL, 0x00934dac1fb96dbdULL, + 0x008470e801162697ULL, 0x005bc2196cd4ad49ULL, + 0x00e535601d5087c3ULL, 0x00769888700f497fULL)}, + {FIELD_LITERAL(0x00da7a4b557298adULL, 0x0019d2589ea5df76ULL, + 0x00ef3e38be0c6497ULL, 0x00a9644e1312609aULL, + 0x004592f61b2558daULL, 0x0082c1df510d7e46ULL, + 0x0042809a535c0023ULL, 0x00215bcb5afd7757ULL)}, + }}, {{ + {FIELD_LITERAL(0x002b9df55a1a4213ULL, 0x00dcfc3b464a26beULL, + 0x00c4f9e07a8144d5ULL, 0x00c8e0617a92b602ULL, + 0x008e3c93accafae0ULL, 0x00bf1bcb95b2ca60ULL, + 0x004ce2426a613bf3ULL, 0x00266cac58e40921ULL)}, + {FIELD_LITERAL(0x008456d5db76e8f0ULL, 0x0032ca9cab2ce163ULL, + 0x0059f2b8bf91abcfULL, 0x0063c2a021712788ULL, + 0x00f86155af22f72dULL, 0x00db98b2a6c005a0ULL, + 0x00ac6e416a693ac4ULL, 0x007a93572af53226ULL)}, + {FIELD_LITERAL(0x0087767520f0de22ULL, 0x0091f64012279fb5ULL, + 0x001050f1f0644999ULL, 0x004f097a2477ad3cULL, + 0x006b37913a9947bdULL, 0x001a3d78645af241ULL, + 0x0057832bbb3008a7ULL, 0x002c1d902b80dc20ULL)}, + }}, {{ + {FIELD_LITERAL(0x001a6002bf178877ULL, 0x009bce168aa5af50ULL, + 0x005fc318ff04a7f5ULL, 0x0052818f55c36461ULL, + 0x008768f5d4b24afbULL, 0x0037ffbae7b69c85ULL, + 0x0018195a4b61edc0ULL, 0x001e12ea088434b2ULL)}, + {FIELD_LITERAL(0x0047d3f804e7ab07ULL, 0x00a809ab5f905260ULL, + 0x00b3ffc7cdaf306dULL, 0x00746e8ec2d6e509ULL, + 0x00d0dade8887a645ULL, 0x00acceeebde0dd37ULL, + 0x009bc2579054686bULL, 0x0023804f97f1c2bfULL)}, + {FIELD_LITERAL(0x0043e2e2e50b80d7ULL, 0x00143aafe4427e0fULL, + 0x005594aaecab855bULL, 0x008b12ccaaecbc01ULL, + 0x002deeb091082bc3ULL, 0x009cca4be2ae7514ULL, + 0x00142b96e696d047ULL, 0x00ad2a2b1c05256aULL)}, + }}, {{ + {FIELD_LITERAL(0x003914f2f144b78bULL, 0x007a95dd8bee6f68ULL, + 0x00c7f4384d61c8e6ULL, 0x004e51eb60f1bdb2ULL, + 0x00f64be7aa4621d8ULL, 0x006797bfec2f0ac0ULL, + 0x007d17aab3c75900ULL, 0x001893e73cac8bc5ULL)}, + {FIELD_LITERAL(0x00140360b768665bULL, 0x00b68aca4967f977ULL, + 0x0001089b66195ae4ULL, 0x00fe71122185e725ULL, + 0x000bca2618d49637ULL, 0x00a54f0557d7e98aULL, + 0x00cdcd2f91d6f417ULL, 0x00ab8c13741fd793ULL)}, + {FIELD_LITERAL(0x00725ee6b1e549e0ULL, 0x007124a0769777faULL, + 0x000b68fdad07ae42ULL, 0x0085b909cd4952dfULL, + 0x0092d2e3c81606f4ULL, 0x009f22f6cac099a0ULL, + 0x00f59da57f2799a8ULL, 0x00f06c090122f777ULL)}, + }}, {{ + {FIELD_LITERAL(0x00ce0bed0a3532bcULL, 0x001a5048a22df16bULL, + 0x00e31db4cbad8bf1ULL, 0x00e89292120cf00eULL, + 0x007d1dd1a9b00034ULL, 0x00e2a9041ff8f680ULL, + 0x006a4c837ae596e7ULL, 0x00713af1068070b3ULL)}, + {FIELD_LITERAL(0x00c4fe64ce66d04bULL, 0x00b095d52e09b3d7ULL, + 0x00758bbecb1a3a8eULL, 0x00f35cce8d0650c0ULL, + 0x002b878aa5984473ULL, 0x0062e0a3b7544ddcULL, + 0x00b25b290ed116feULL, 0x007b0f6abe0bebf2ULL)}, + {FIELD_LITERAL(0x0081d4e3addae0a8ULL, 0x003410c836c7ffccULL, + 0x00c8129ad89e4314ULL, 0x000e3d5a23922dcdULL, + 0x00d91e46f29c31f3ULL, 0x006c728cde8c5947ULL, + 0x002bc655ba2566c0ULL, 0x002ca94721533108ULL)}, + }}, {{ + {FIELD_LITERAL(0x0051e4b3f764d8a9ULL, 0x0019792d46e904a0ULL, + 0x00853bc13dbc8227ULL, 0x000840208179f12dULL, + 0x0068243474879235ULL, 0x0013856fbfe374d0ULL, + 0x00bda12fe8676424ULL, 0x00bbb43635926eb2ULL)}, + {FIELD_LITERAL(0x0012cdc880a93982ULL, 0x003c495b21cd1b58ULL, + 0x00b7e5c93f22a26eULL, 0x0044aa82dfb99458ULL, + 0x009ba092cdffe9c0ULL, 0x00a14b3ab2083b73ULL, + 0x000271c2f70e1c4bULL, 0x00eea9cac0f66eb8ULL)}, + {FIELD_LITERAL(0x001a1847c4ac5480ULL, 0x00b1b412935bb03aULL, + 0x00f74285983bf2b2ULL, 0x00624138b5b5d0f1ULL, + 0x008820c0b03d38bfULL, 0x00b94e50a18c1572ULL, + 0x0060f6934841798fULL, 0x00c52f5d66d6ebe2ULL)}, + }}, {{ + {FIELD_LITERAL(0x00da23d59f9bcea6ULL, 0x00e0f27007a06a4bULL, + 0x00128b5b43a6758cULL, 0x000cf50190fa8b56ULL, + 0x00fc877aba2b2d72ULL, 0x00623bef52edf53fULL, + 0x00e6af6b819669e2ULL, 0x00e314dc34fcaa4fULL)}, + {FIELD_LITERAL(0x0066e5eddd164d1eULL, 0x00418a7c6fe28238ULL, + 0x0002e2f37e962c25ULL, 0x00f01f56b5975306ULL, + 0x0048842fa503875cULL, 0x0057b0e968078143ULL, + 0x00ff683024f3d134ULL, 0x0082ae28fcad12e4ULL)}, + {FIELD_LITERAL(0x0011ddfd21260e42ULL, 0x00d05b0319a76892ULL, + 0x00183ea4368e9b8fULL, 0x00b0815662affc96ULL, + 0x00b466a5e7ce7c88ULL, 0x00db93b07506e6eeULL, + 0x0033885f82f62401ULL, 0x0086f9090ec9b419ULL)}, + }}, {{ + {FIELD_LITERAL(0x00d95d1c5fcb435aULL, 0x0016d1ed6b5086f9ULL, + 0x00792aa0b7e54d71ULL, 0x0067b65715f1925dULL, + 0x00a219755ec6176bULL, 0x00bc3f026b12c28fULL, + 0x00700c897ffeb93eULL, 0x0089b83f6ec50b46ULL)}, + {FIELD_LITERAL(0x003c97e6384da36eULL, 0x00423d53eac81a09ULL, + 0x00b70d68f3cdce35ULL, 0x00ee7959b354b92cULL, + 0x00f4e9718819c8caULL, 0x009349f12acbffe9ULL, + 0x005aee7b62cb7da6ULL, 0x00d97764154ffc86ULL)}, + {FIELD_LITERAL(0x00526324babb46dcULL, 0x002ee99b38d7bf9eULL, + 0x007ea51794706ef4ULL, 0x00abeb04da6e3c39ULL, + 0x006b457c1d281060ULL, 0x00fe243e9a66c793ULL, + 0x00378de0fb6c6ee4ULL, 0x003e4194b9c3cb93ULL)}, + }}, {{ + {FIELD_LITERAL(0x00fed3cd80ca2292ULL, 0x0015b043a73ca613ULL, + 0x000a9fd7bf9be227ULL, 0x003b5e03de2db983ULL, + 0x005af72d46904ef7ULL, 0x00c0f1b5c49faa99ULL, + 0x00dc86fc3bd305e1ULL, 0x00c92f08c1cb1797ULL)}, + {FIELD_LITERAL(0x0079680ce111ed3bULL, 0x001a1ed82806122cULL, + 0x000c2e7466d15df3ULL, 0x002c407f6f7150fdULL, + 0x00c5e7c96b1b0ce3ULL, 0x009aa44626863ff9ULL, + 0x00887b8b5b80be42ULL, 0x00b6023cec964825ULL)}, + {FIELD_LITERAL(0x00e4a8e1048970c8ULL, 0x0062887b7830a302ULL, + 0x00bcf1c8cd81402bULL, 0x0056dbb81a68f5beULL, + 0x0014eced83f12452ULL, 0x00139e1a510150dfULL, + 0x00bb81140a82d1a3ULL, 0x000febcc1aaf1aa7ULL)}, + }}, {{ + {FIELD_LITERAL(0x00a7527958238159ULL, 0x0013ec9537a84cd6ULL, + 0x001d7fee7d562525ULL, 0x00b9eefa6191d5e5ULL, + 0x00dbc97db70bcb8aULL, 0x00481affc7a4d395ULL, + 0x006f73d3e70c31bbULL, 0x00183f324ed96a61ULL)}, + {FIELD_LITERAL(0x0039dd7ce7fc6860ULL, 0x00d64f6425653da1ULL, + 0x003e037c7f57d0afULL, 0x0063477a06e2bcf2ULL, + 0x001727dbb7ac67e6ULL, 0x0049589f5efafe2eULL, + 0x00fc0fef2e813d54ULL, 0x008baa5d087fb50dULL)}, + {FIELD_LITERAL(0x0024fb59d9b457c7ULL, 0x00a7d4e060223e4cULL, + 0x00c118d1b555fd80ULL, 0x0082e216c732f22aULL, + 0x00cd2a2993089504ULL, 0x003638e836a3e13dULL, + 0x000d855ee89b4729ULL, 0x008ec5b7d4810c91ULL)}, + }}, {{ + {FIELD_LITERAL(0x001bf51f7d65cdfdULL, 0x00d14cdafa16a97dULL, + 0x002c38e60fcd10e7ULL, 0x00a27446e393efbdULL, + 0x000b5d8946a71fddULL, 0x0063df2cde128f2fULL, + 0x006c8679569b1888ULL, 0x0059ffc4925d732dULL)}, + {FIELD_LITERAL(0x00ece96f95f2b66fULL, 0x00ece7952813a27bULL, + 0x0026fc36592e489eULL, 0x007157d1a2de0f66ULL, + 0x00759dc111d86ddfULL, 0x0012881e5780bb0fULL, + 0x00c8ccc83ad29496ULL, 0x0012b9bd1929eb71ULL)}, + {FIELD_LITERAL(0x000fa15a20da5df0ULL, 0x00349ddb1a46cd31ULL, + 0x002c512ad1d8e726ULL, 0x00047611f669318dULL, + 0x009e68fba591e17eULL, 0x004320dffa803906ULL, + 0x00a640874951a3d3ULL, 0x00b6353478baa24fULL)}, + }}, {{ + {FIELD_LITERAL(0x009696510000d333ULL, 0x00ec2f788bc04826ULL, + 0x000e4d02b1f67ba5ULL, 0x00659aa8dace08b6ULL, + 0x00d7a38a3a3ae533ULL, 0x008856defa8c746bULL, + 0x004d7a4402d3da1aULL, 0x00ea82e06229260fULL)}, + {FIELD_LITERAL(0x006a15bb20f75c0cULL, 0x0079a144027a5d0cULL, + 0x00d19116ce0b4d70ULL, 0x0059b83bcb0b268eULL, + 0x005f58f63f16c127ULL, 0x0079958318ee2c37ULL, + 0x00defbb063d07f82ULL, 0x00f1f0b931d2d446ULL)}, + {FIELD_LITERAL(0x00cb5e4c3c35d422ULL, 0x008df885ca43577fULL, + 0x00fa50b16ca3e471ULL, 0x005a0e58e17488c8ULL, + 0x00b2ceccd6d34d19ULL, 0x00f01d5d235e36e9ULL, + 0x00db2e7e4be6ca44ULL, 0x00260ab77f35fccdULL)}, + }}, {{ + {FIELD_LITERAL(0x006f6fd9baac61d5ULL, 0x002a7710a020a895ULL, + 0x009de0db7fc03d4dULL, 0x00cdedcb1875f40bULL, + 0x00050caf9b6b1e22ULL, 0x005e3a6654456ab0ULL, + 0x00775fdf8c4423d4ULL, 0x0028701ea5738b5dULL)}, + {FIELD_LITERAL(0x009ffd90abfeae96ULL, 0x00cba3c2b624a516ULL, + 0x005ef08bcee46c91ULL, 0x00e6fde30afb6185ULL, + 0x00f0b4db4f818ce4ULL, 0x006c54f45d2127f5ULL, + 0x00040125035854c7ULL, 0x00372658a3287e13ULL)}, + {FIELD_LITERAL(0x00d7070fb1beb2abULL, 0x0078fc845a93896bULL, + 0x006894a4b2f224a6ULL, 0x005bdd8192b9dbdeULL, + 0x00b38839874b3a9eULL, 0x00f93618b04b7a57ULL, + 0x003e3ec75fd2c67eULL, 0x00bf5e6bfc29494aULL)}, + }}, {{ + {FIELD_LITERAL(0x00f19224ebba2aa5ULL, 0x0074f89d358e694dULL, + 0x00eea486597135adULL, 0x0081579a4555c7e1ULL, + 0x0010b9b872930a9dULL, 0x00f002e87a30ecc0ULL, + 0x009b9d66b6de56e2ULL, 0x00a3c4f45e8004ebULL)}, + {FIELD_LITERAL(0x0045e8dda9400888ULL, 0x002ff12e5fc05db7ULL, + 0x00a7098d54afe69cULL, 0x00cdbe846a500585ULL, + 0x00879c1593ca1882ULL, 0x003f7a7fea76c8b0ULL, + 0x002cd73dd0c8e0a1ULL, 0x00645d6ce96f51feULL)}, + {FIELD_LITERAL(0x002b7e83e123d6d6ULL, 0x00398346f7419c80ULL, + 0x0042922e55940163ULL, 0x005e7fc5601886a3ULL, + 0x00e88f2cee1d3103ULL, 0x00e7fab135f2e377ULL, + 0x00b059984dbf0dedULL, 0x0009ce080faa5bb8ULL)}, + }}, {{ + {FIELD_LITERAL(0x0085e78af7758979ULL, 0x00275a4ee1631a3aULL, + 0x00d26bc0ed78b683ULL, 0x004f8355ea21064fULL, + 0x00d618e1a32696e5ULL, 0x008d8d7b150e5680ULL, + 0x00a74cd854b278d2ULL, 0x001dd62702203ea0ULL)}, + {FIELD_LITERAL(0x00f89335c2a59286ULL, 0x00a0f5c905d55141ULL, + 0x00b41fb836ee9382ULL, 0x00e235d51730ca43ULL, + 0x00a5cb37b5c0a69aULL, 0x009b966ffe136c45ULL, + 0x00cb2ea10bf80ed1ULL, 0x00fb2b370b40dc35ULL)}, + {FIELD_LITERAL(0x00d687d16d4ee8baULL, 0x0071520bdd069dffULL, + 0x00de85c60d32355dULL, 0x0087d2e3565102f4ULL, + 0x00cde391b8dfc9aaULL, 0x00e18d69efdfefe5ULL, + 0x004a9d0591954e91ULL, 0x00fa36dd8b50eee5ULL)}, + }}, {{ + {FIELD_LITERAL(0x002e788749a865f7ULL, 0x006e4dc3116861eaULL, + 0x009f1428c37276e6ULL, 0x00e7d2e0fc1e1226ULL, + 0x003aeebc6b6c45f6ULL, 0x0071a8073bf500c9ULL, + 0x004b22ad986b530cULL, 0x00f439e63c0d79d4ULL)}, + {FIELD_LITERAL(0x006bc3d53011f470ULL, 0x00032d6e692b83e8ULL, + 0x00059722f497cd0bULL, 0x0009b4e6f0c497ccULL, + 0x0058a804b7cce6c0ULL, 0x002b71d3302bbd5dULL, + 0x00e2f82a36765fceULL, 0x008dded99524c703ULL)}, + {FIELD_LITERAL(0x004d058953747d64ULL, 0x00701940fe79aa6fULL, + 0x00a620ac71c760bfULL, 0x009532b611158b75ULL, + 0x00547ed7f466f300ULL, 0x003cb5ab53a8401aULL, + 0x00c7763168ce3120ULL, 0x007e48e33e4b9ab2ULL)}, + }}, {{ + {FIELD_LITERAL(0x001b2fc57bf3c738ULL, 0x006a3f918993fb80ULL, + 0x0026f7a14fdec288ULL, 0x0075a2cdccef08dbULL, + 0x00d3ecbc9eecdbf1ULL, 0x0048c40f06e5bf7fULL, + 0x00d63e423009896bULL, 0x000598bc99c056a8ULL)}, + {FIELD_LITERAL(0x002f194eaafa46dcULL, 0x008e38f57fe87613ULL, + 0x00dc8e5ae25f4ab2ULL, 0x000a17809575e6bdULL, + 0x00d3ec7923ba366aULL, 0x003a7e72e0ad75e3ULL, + 0x0010024b88436e0aULL, 0x00ed3c5444b64051ULL)}, + {FIELD_LITERAL(0x00831fc1340af342ULL, 0x00c9645669466d35ULL, + 0x007692b4cc5a080fULL, 0x009fd4a47ac9259fULL, + 0x001eeddf7d45928bULL, 0x003c0446fc45f28bULL, + 0x002c0713aa3e2507ULL, 0x0095706935f0f41eULL)}, + }}, {{ + {FIELD_LITERAL(0x00766ae4190ec6d8ULL, 0x0065768cabc71380ULL, + 0x00b902598416cdc2ULL, 0x00380021ad38df52ULL, + 0x008f0b89d6551134ULL, 0x004254d4cc62c5a5ULL, + 0x000d79f4484b9b94ULL, 0x00b516732ae3c50eULL)}, + {FIELD_LITERAL(0x001fb73475c45509ULL, 0x00d2b2e5ea43345aULL, + 0x00cb3c3842077bd1ULL, 0x0029f90ad820946eULL, + 0x007c11b2380778aaULL, 0x009e54ece62c1704ULL, + 0x004bc60c41ca01c3ULL, 0x004525679a5a0b03ULL)}, + {FIELD_LITERAL(0x00c64fbddbed87b3ULL, 0x0040601d11731faaULL, + 0x009c22475b6f9d67ULL, 0x0024b79dae875f15ULL, + 0x00616fed3f02c3b0ULL, 0x0000cf39f6af2d3bULL, + 0x00c46bac0aa9a688ULL, 0x00ab23e2800da204ULL)}, + }}, {{ + {FIELD_LITERAL(0x000b3a37617632b0ULL, 0x00597199fe1cfb6cULL, + 0x0042a7ccdfeafdd6ULL, 0x004cc9f15ebcea17ULL, + 0x00f436e596a6b4a4ULL, 0x00168861142df0d8ULL, + 0x000753edfec26af5ULL, 0x000c495d7e388116ULL)}, + {FIELD_LITERAL(0x0017085f4a346148ULL, 0x00c7cf7a37f62272ULL, + 0x001776e129bc5c30ULL, 0x009955134c9eef2aULL, + 0x001ba5bdf1df07beULL, 0x00ec39497103a55cULL, + 0x006578354fda6cfbULL, 0x005f02719d4f15eeULL)}, + {FIELD_LITERAL(0x0052b9d9b5d9655dULL, 0x00d4ec7ba1b461c3ULL, + 0x00f95df4974f280bULL, 0x003d8e5ca11aeb51ULL, + 0x00d4981eb5a70b26ULL, 0x000af9a4f6659f29ULL, + 0x004598c846faeb43ULL, 0x0049d9a183a47670ULL)}, + }}, {{ + {FIELD_LITERAL(0x000a72d23dcb3f1fULL, 0x00a3737f84011727ULL, + 0x00f870c0fbbf4a47ULL, 0x00a7aadd04b5c9caULL, + 0x000c7715c67bd072ULL, 0x00015a136afcd74eULL, + 0x0080d5caea499634ULL, 0x0026b448ec7514b7ULL)}, + {FIELD_LITERAL(0x00b60167d9e7d065ULL, 0x00e60ba0d07381e8ULL, + 0x003a4f17b725c2d4ULL, 0x006c19fe176b64faULL, + 0x003b57b31af86ccbULL, 0x0021047c286180fdULL, + 0x00bdc8fb00c6dbb6ULL, 0x00fe4a9f4bab4f3fULL)}, + {FIELD_LITERAL(0x0088ffc3a16111f7ULL, 0x009155e4245d0bc8ULL, + 0x00851d68220572d5ULL, 0x00557ace1e514d29ULL, + 0x0031d7c339d91022ULL, 0x00101d0ae2eaceeaULL, + 0x00246ab3f837b66aULL, 0x00d5216d381ff530ULL)}, + }}, {{ + {FIELD_LITERAL(0x0057e7ea35f36daeULL, 0x00f47d7ad15de22eULL, + 0x00d757ea4b105115ULL, 0x008311457d579d7eULL, + 0x00b49b75b1edd4ebULL, 0x0081c7ff742fd63aULL, + 0x00ddda3187433df6ULL, 0x00475727d55f9c66ULL)}, + {FIELD_LITERAL(0x00a6295218dc136aULL, 0x00563b3af0e9c012ULL, + 0x00d3753b0145db1bULL, 0x004550389c043dc1ULL, + 0x00ea94ae27401bdfULL, 0x002b0b949f2b7956ULL, + 0x00c63f780ad8e23cULL, 0x00e591c47d6bab15ULL)}, + {FIELD_LITERAL(0x00416c582b058eb6ULL, 0x004107da5b2cc695ULL, + 0x00b3cd2556aeec64ULL, 0x00c0b418267e57a1ULL, + 0x001799293579bd2eULL, 0x0046ed44590e4d07ULL, + 0x001d7459b3630a1eULL, 0x00c6afba8b6696aaULL)}, + }}, {{ + {FIELD_LITERAL(0x008d6009b26da3f8ULL, 0x00898e88ca06b1caULL, + 0x00edb22b2ed7fe62ULL, 0x00fbc93516aabe80ULL, + 0x008b4b470c42ce0dULL, 0x00e0032ba7d0dcbbULL, + 0x00d76da3a956ecc8ULL, 0x007f20fe74e3852aULL)}, + {FIELD_LITERAL(0x002419222c607674ULL, 0x00a7f23af89188b3ULL, + 0x00ad127284e73d1cULL, 0x008bba582fae1c51ULL, + 0x00fc6aa7ca9ecab1ULL, 0x003df5319eb6c2baULL, + 0x002a05af8a8b199aULL, 0x004bf8354558407cULL)}, + {FIELD_LITERAL(0x00ce7d4a30f0fcbfULL, 0x00d02c272629f03dULL, + 0x0048c001f7400bc2ULL, 0x002c21368011958dULL, + 0x0098a550391e96b5ULL, 0x002d80b66390f379ULL, + 0x001fa878760cc785ULL, 0x001adfce54b613d5ULL)}, + }}, {{ + {FIELD_LITERAL(0x001ed4dc71fa2523ULL, 0x005d0bff19bf9b5cULL, + 0x00c3801cee065a64ULL, 0x001ed0b504323fbfULL, + 0x0003ab9fdcbbc593ULL, 0x00df82070178b8d2ULL, + 0x00a2bcaa9c251f85ULL, 0x00c628a3674bd02eULL)}, + {FIELD_LITERAL(0x006b7a0674f9f8deULL, 0x00a742414e5c7cffULL, + 0x0041cbf3c6e13221ULL, 0x00e3a64fd207af24ULL, + 0x0087c05f15fbe8d1ULL, 0x004c50936d9e8a33ULL, + 0x001306ec21042b6dULL, 0x00a4f4137d1141c2ULL)}, + {FIELD_LITERAL(0x0009e6fb921568b0ULL, 0x00b3c60120219118ULL, + 0x002a6c3460dd503aULL, 0x009db1ef11654b54ULL, + 0x0063e4bf0be79601ULL, 0x00670d34bb2592b9ULL, + 0x00dcee2f6c4130ceULL, 0x00b2682e88e77f54ULL)}, + }}, {{ + {FIELD_LITERAL(0x000d5b4b3da135abULL, 0x00838f3e5064d81dULL, + 0x00d44eb50f6d94edULL, 0x0008931ab502ac6dULL, + 0x00debe01ca3d3586ULL, 0x0025c206775f0641ULL, + 0x005ad4b6ae912763ULL, 0x007e2c318ad8f247ULL)}, + {FIELD_LITERAL(0x00ddbe0750dd1addULL, 0x004b3c7b885844b8ULL, + 0x00363e7ecf12f1aeULL, 0x0062e953e6438f9dULL, + 0x0023cc73b076afe9ULL, 0x00b09fa083b4da32ULL, + 0x00c7c3d2456c541dULL, 0x005b591ec6b694d4ULL)}, + {FIELD_LITERAL(0x0028656e19d62fcfULL, 0x0052a4af03df148dULL, + 0x00122765ddd14e42ULL, 0x00f2252904f67157ULL, + 0x004741965b636f3aULL, 0x006441d296132cb9ULL, + 0x005e2106f956a5b7ULL, 0x00247029592d335cULL)}, + }}, {{ + {FIELD_LITERAL(0x003fe038eb92f894ULL, 0x000e6da1b72e8e32ULL, + 0x003a1411bfcbe0faULL, 0x00b55d473164a9e4ULL, + 0x00b9a775ac2df48dULL, 0x0002ddf350659e21ULL, + 0x00a279a69eb19cb3ULL, 0x00f844eab25cba44ULL)}, + {FIELD_LITERAL(0x00c41d1f9c1f1ac1ULL, 0x007b2df4e9f19146ULL, + 0x00b469355fd5ba7aULL, 0x00b5e1965afc852aULL, + 0x00388d5f1e2d8217ULL, 0x0022079e4c09ae93ULL, + 0x0014268acd4ef518ULL, 0x00c1dd8d9640464cULL)}, + {FIELD_LITERAL(0x0038526adeed0c55ULL, 0x00dd68c607e3fe85ULL, + 0x00f746ddd48a5d57ULL, 0x0042f2952b963b7cULL, + 0x001cbbd6876d5ec2ULL, 0x005e341470bca5c2ULL, + 0x00871d41e085f413ULL, 0x00e53ab098f45732ULL)}, + }}, {{ + {FIELD_LITERAL(0x004d51124797c831ULL, 0x008f5ae3750347adULL, + 0x0070ced94c1a0c8eULL, 0x00f6db2043898e64ULL, + 0x000d00c9a5750cd0ULL, 0x000741ec59bad712ULL, + 0x003c9d11aab37b7fULL, 0x00a67ba169807714ULL)}, + {FIELD_LITERAL(0x00adb2c1566e8b8fULL, 0x0096c68a35771a9aULL, + 0x00869933356f334aULL, 0x00ba9c93459f5962ULL, + 0x009ec73fb6e8ca4bULL, 0x003c3802c27202e1ULL, + 0x0031f5b733e0c008ULL, 0x00f9058c19611fa9ULL)}, + {FIELD_LITERAL(0x00238f01814a3421ULL, 0x00c325a44b6cce28ULL, + 0x002136f97aeb0e73ULL, 0x000cac8268a4afe2ULL, + 0x0022fd218da471b3ULL, 0x009dcd8dfff8def9ULL, + 0x00cb9f8181d999bbULL, 0x00143ae56edea349ULL)}, + }}, {{ + {FIELD_LITERAL(0x0000623bf87622c5ULL, 0x00a1966fdd069496ULL, + 0x00c315b7b812f9fcULL, 0x00bdf5efcd128b97ULL, + 0x001d464f532e3e16ULL, 0x003cd94f081bfd7eULL, + 0x00ed9dae12ce4009ULL, 0x002756f5736eee70ULL)}, + {FIELD_LITERAL(0x00a5187e6ee7341bULL, 0x00e6d52e82d83b6eULL, + 0x00df3c41323094a7ULL, 0x00b3324f444e9de9ULL, + 0x00689eb21a35bfe5ULL, 0x00f16363becd548dULL, + 0x00e187cc98e7f60fULL, 0x00127d9062f0ccabULL)}, + {FIELD_LITERAL(0x004ad71b31c29e40ULL, 0x00a5fcace12fae29ULL, + 0x004425b5597280edULL, 0x00e7ef5d716c3346ULL, + 0x0010b53ada410ac8ULL, 0x0092310226060c9bULL, + 0x0091c26128729c7eULL, 0x0088b42900f8ec3bULL)}, + }}, {{ + {FIELD_LITERAL(0x00f1e26e9762d4a8ULL, 0x00d9d74082183414ULL, + 0x00ffec9bd57a0282ULL, 0x000919e128fd497aULL, + 0x00ab7ae7d00fe5f8ULL, 0x0054dc442851ff68ULL, + 0x00c9ebeb3b861687ULL, 0x00507f7cab8b698fULL)}, + {FIELD_LITERAL(0x00c13c5aae3ae341ULL, 0x009c6c9ed98373e7ULL, + 0x00098f26864577a8ULL, 0x0015b886e9488b45ULL, + 0x0037692c42aadba5ULL, 0x00b83170b8e7791cULL, + 0x001670952ece1b44ULL, 0x00fd932a39276da2ULL)}, + {FIELD_LITERAL(0x0081a3259bef3398ULL, 0x005480fff416107bULL, + 0x00ce4f607d21be98ULL, 0x003ffc084b41df9bULL, + 0x0043d0bb100502d1ULL, 0x00ec35f575ba3261ULL, + 0x00ca18f677300ef3ULL, 0x00e8bb0a827d8548ULL)}, + }}, {{ + {FIELD_LITERAL(0x00df76b3328ada72ULL, 0x002e20621604a7c2ULL, + 0x00f910638a105b09ULL, 0x00ef4724d96ef2cdULL, + 0x00377d83d6b8a2f7ULL, 0x00b4f48805ade324ULL, + 0x001cd5da8b152018ULL, 0x0045af671a20ca7fULL)}, + {FIELD_LITERAL(0x009ae3b93a56c404ULL, 0x004a410b7a456699ULL, + 0x00023a619355e6b2ULL, 0x009cdc7297387257ULL, + 0x0055b94d4ae70d04ULL, 0x002cbd607f65b005ULL, + 0x003208b489697166ULL, 0x00ea2aa058867370ULL)}, + {FIELD_LITERAL(0x00f29d2598ee3f32ULL, 0x00b4ac5385d82adcULL, + 0x007633eaf04df19bULL, 0x00aa2d3d77ceab01ULL, + 0x004a2302fcbb778aULL, 0x00927f225d5afa34ULL, + 0x004a8e9d5047f237ULL, 0x008224ae9dbce530ULL)}, + }}, {{ + {FIELD_LITERAL(0x001cf640859b02f8ULL, 0x00758d1d5d5ce427ULL, + 0x00763c784ef4604cULL, 0x005fa81aee205270ULL, + 0x00ac537bfdfc44cbULL, 0x004b919bd342d670ULL, + 0x00238508d9bf4b7aULL, 0x00154888795644f3ULL)}, + {FIELD_LITERAL(0x00c845923c084294ULL, 0x00072419a201bc25ULL, + 0x0045f408b5f8e669ULL, 0x00e9d6a186b74dfeULL, + 0x00e19108c68fa075ULL, 0x0017b91d874177b7ULL, + 0x002f0ca2c7912c5aULL, 0x009400aa385a90a2ULL)}, + {FIELD_LITERAL(0x0071110b01482184ULL, 0x00cfed0044f2bef8ULL, + 0x0034f2901cf4662eULL, 0x003b4ae2a67f9834ULL, + 0x00cca9b96fe94810ULL, 0x00522507ae77abd0ULL, + 0x00bac7422721e73eULL, 0x0066622b0f3a62b0ULL)}, + }}, {{ + {FIELD_LITERAL(0x00f8ac5cf4705b6aULL, 0x00867d82dcb457e3ULL, + 0x007e13ab2ccc2ce9ULL, 0x009ee9a018d3930eULL, + 0x008370f8ecb42df8ULL, 0x002d9f019add263eULL, + 0x003302385b92d196ULL, 0x00a15654536e2c0cULL)}, + {FIELD_LITERAL(0x0026ef1614e160afULL, 0x00c023f9edfc9c76ULL, + 0x00cff090da5f57baULL, 0x0076db7a66643ae9ULL, + 0x0019462f8c646999ULL, 0x008fec00b3854b22ULL, + 0x00d55041692a0a1cULL, 0x0065db894215ca00ULL)}, + {FIELD_LITERAL(0x00a925036e0a451cULL, 0x002a0390c36b6cc1ULL, + 0x00f27020d90894f4ULL, 0x008d90d52cbd3d7fULL, + 0x00e1d0137392f3b8ULL, 0x00f017c158b51a8fULL, + 0x00cac313d3ed7dbcULL, 0x00b99a81e3eb42d3ULL)}, + }}, {{ + {FIELD_LITERAL(0x00b54850275fe626ULL, 0x0053a3fd1ec71140ULL, + 0x00e3d2d7dbe096faULL, 0x00e4ac7b595cce4cULL, + 0x0077bad449c0a494ULL, 0x00b7c98814afd5b3ULL, + 0x0057226f58486cf9ULL, 0x00b1557154f0cc57ULL)}, + {FIELD_LITERAL(0x008cc9cd236315c0ULL, 0x0031d9c5b39fda54ULL, + 0x00a5713ef37e1171ULL, 0x00293d5ae2886325ULL, + 0x00c4aba3e05015e1ULL, 0x0003f35ef78e4fc6ULL, + 0x0039d6bd3ac1527bULL, 0x0019d7c3afb77106ULL)}, + {FIELD_LITERAL(0x007b162931a985afULL, 0x00ad40a2e0daa713ULL, + 0x006df27c4009f118ULL, 0x00503e9f4e2e8becULL, + 0x00751a77c82c182dULL, 0x000298937769245bULL, + 0x00ffb1e8fabf9ee5ULL, 0x0008334706e09abeULL)}, + }}, {{ + {FIELD_LITERAL(0x00dbca4e98a7dcd9ULL, 0x00ee29cfc78bde99ULL, + 0x00e4a3b6995f52e9ULL, 0x0045d70189ae8096ULL, + 0x00fd2a8a3b9b0d1bULL, 0x00af1793b107d8e1ULL, + 0x00dbf92cbe4afa20ULL, 0x00da60f798e3681dULL)}, + {FIELD_LITERAL(0x004246bfcecc627aULL, 0x004ba431246c03a4ULL, + 0x00bd1d101872d497ULL, 0x003b73d3f185ee16ULL, + 0x001feb2e2678c0e3ULL, 0x00ff13c5a89dec76ULL, + 0x00ed06042e771d8fULL, 0x00a4fd2a897a83ddULL)}, + {FIELD_LITERAL(0x009a4a3be50d6597ULL, 0x00de3165fc5a1096ULL, + 0x004f3f56e345b0c7ULL, 0x00f7bf721d5ab8bcULL, + 0x004313e47b098c50ULL, 0x00e4c7d5c0e1adbbULL, + 0x002e3e3db365051eULL, 0x00a480c2cd6a96fbULL)}, + }}, {{ + {FIELD_LITERAL(0x00417fa30a7119edULL, 0x00af257758419751ULL, + 0x00d358a487b463d4ULL, 0x0089703cc720b00dULL, + 0x00ce56314ff7f271ULL, 0x0064db171ade62c1ULL, + 0x00640b36d4a22fedULL, 0x00424eb88696d23fULL)}, + {FIELD_LITERAL(0x004ede34af2813f3ULL, 0x00d4a8e11c9e8216ULL, + 0x004796d5041de8a5ULL, 0x00c4c6b4d21cc987ULL, + 0x00e8a433ee07fa1eULL, 0x0055720b5abcc5a1ULL, + 0x008873ea9c74b080ULL, 0x005b3fec1ab65d48ULL)}, + {FIELD_LITERAL(0x0047e5277db70ec5ULL, 0x000a096c66db7d6bULL, + 0x00b4164cc1730159ULL, 0x004a9f783fe720feULL, + 0x00a8177b94449dbcULL, 0x0095a24ff49a599fULL, + 0x0069c1c578250cbcULL, 0x00452019213debf4ULL)}, + }}, {{ + {FIELD_LITERAL(0x0021ce99e09ebda3ULL, 0x00fcbd9f91875ad0ULL, + 0x009bbf6b7b7a0b5fULL, 0x00388886a69b1940ULL, + 0x00926a56d0f81f12ULL, 0x00e12903c3358d46ULL, + 0x005dfce4e8e1ce9dULL, 0x0044cfa94e2f7e23ULL)}, + {FIELD_LITERAL(0x001bd59c09e982eaULL, 0x00f72daeb937b289ULL, + 0x0018b76dca908e0eULL, 0x00edb498512384adULL, + 0x00ce0243b6cc9538ULL, 0x00f96ff690cb4e70ULL, + 0x007c77bf9f673c8dULL, 0x005bf704c088a528ULL)}, + {FIELD_LITERAL(0x0093d4628dcb33beULL, 0x0095263d51d42582ULL, + 0x0049b3222458fe06ULL, 0x00e7fce73b653a7fULL, + 0x003ca2ebce60b369ULL, 0x00c5de239a32bea4ULL, + 0x0063b8b3d71fb6bfULL, 0x0039aeeb78a1a839ULL)}, + }}, {{ + {FIELD_LITERAL(0x007dc52da400336cULL, 0x001fded1e15b9457ULL, + 0x00902e00f5568e3aULL, 0x00219bef40456d2dULL, + 0x005684161fb3dbc9ULL, 0x004a4e9be49a76eaULL, + 0x006e685ae88b78ffULL, 0x0021c42f13042d3cULL)}, + {FIELD_LITERAL(0x00fb22bb5fd3ce50ULL, 0x0017b48aada7ae54ULL, + 0x00fd5c44ad19a536ULL, 0x000ccc4e4e55e45cULL, + 0x00fd637d45b4c3f5ULL, 0x0038914e023c37cfULL, + 0x00ac1881d6a8d898ULL, 0x00611ed8d3d943a8ULL)}, + {FIELD_LITERAL(0x0056e2259d113d2bULL, 0x00594819b284ec16ULL, + 0x00c7bf794bb36696ULL, 0x00721ee75097cdc6ULL, + 0x00f71be9047a2892ULL, 0x00df6ba142564edfULL, + 0x0069580b7a184e8dULL, 0x00f056e38fca0feeULL)}, + }}, {{ + {FIELD_LITERAL(0x009df98566a18c6dULL, 0x00cf3a200968f219ULL, + 0x0044ba60da6d9086ULL, 0x00dbc9c0e344da03ULL, + 0x000f9401c4466855ULL, 0x00d46a57c5b0a8d1ULL, + 0x00875a635d7ac7c6ULL, 0x00ef4a933b7e0ae6ULL)}, + {FIELD_LITERAL(0x005e8694077a1535ULL, 0x008bef75f71c8f1dULL, + 0x000a7c1316423511ULL, 0x00906e1d70604320ULL, + 0x003fc46c1a2ffbd6ULL, 0x00d1d5022e68f360ULL, + 0x002515fba37bbf46ULL, 0x00ca16234e023b44ULL)}, + {FIELD_LITERAL(0x00787c99561f4690ULL, 0x00a857a8c1561f27ULL, + 0x00a10df9223c09feULL, 0x00b98a9562e3b154ULL, + 0x004330b8744c3ed2ULL, 0x00e06812807ec5c4ULL, + 0x00e4cf6a7db9f1e3ULL, 0x00d95b089f132a34ULL)}, + }}, {{ + {FIELD_LITERAL(0x002922b39ca33eecULL, 0x0090d12a5f3ab194ULL, + 0x00ab60c02fb5f8edULL, 0x00188d292abba1cfULL, + 0x00e10edec9698f6eULL, 0x0069a4d9934133c8ULL, + 0x0024aac40e6d3d06ULL, 0x001702c2177661b0ULL)}, + {FIELD_LITERAL(0x00139078397030bdULL, 0x000e3c447e859a00ULL, + 0x0064a5b334c82393ULL, 0x00b8aabeb7358093ULL, + 0x00020778bb9ae73bULL, 0x0032ee94c7892a18ULL, + 0x008215253cb41bdaULL, 0x005e2797593517aeULL)}, + {FIELD_LITERAL(0x0083765a5f855d4aULL, 0x0051b6d1351b8ee2ULL, + 0x00116de548b0f7bbULL, 0x0087bd88703affa0ULL, + 0x0095b2cc34d7fdd2ULL, 0x0084cd81b53f0bc8ULL, + 0x008562fc995350edULL, 0x00a39abb193651e3ULL)}, + }}, {{ + {FIELD_LITERAL(0x0019e23f0474b114ULL, 0x00eb94c2ad3b437eULL, + 0x006ddb34683b75acULL, 0x00391f9209b564c6ULL, + 0x00083b3bb3bff7aaULL, 0x00eedcd0f6dceefcULL, + 0x00b50817f794fe01ULL, 0x0036474deaaa75c9ULL)}, + {FIELD_LITERAL(0x0091868594265aa2ULL, 0x00797accae98ca6dULL, + 0x0008d8c5f0f8a184ULL, 0x00d1f4f1c2b2fe6eULL, + 0x0036783dfb48a006ULL, 0x008c165120503527ULL, + 0x0025fd780058ce9bULL, 0x0068beb007be7d27ULL)}, + {FIELD_LITERAL(0x00d0ff88aa7c90c2ULL, 0x00b2c60dacf53394ULL, + 0x0094a7284d9666d6ULL, 0x00bed9022ce7a19dULL, + 0x00c51553f0cd7682ULL, 0x00c3fb870b124992ULL, + 0x008d0bc539956c9bULL, 0x00fc8cf258bb8885ULL)}, + }}, {{ + {FIELD_LITERAL(0x003667bf998406f8ULL, 0x0000115c43a12975ULL, + 0x001e662f3b20e8fdULL, 0x0019ffa534cb24ebULL, + 0x00016be0dc8efb45ULL, 0x00ff76a8b26243f5ULL, + 0x00ae20d241a541e3ULL, 0x0069bd6af13cd430ULL)}, + {FIELD_LITERAL(0x0045fdc16487cda3ULL, 0x00b2d8e844cf2ed7ULL, + 0x00612c50e88c1607ULL, 0x00a08aabc66c1672ULL, + 0x006031fdcbb24d97ULL, 0x001b639525744b93ULL, + 0x004409d62639ab17ULL, 0x00a1853d0347ab1dULL)}, + {FIELD_LITERAL(0x0075a1a56ebf5c21ULL, 0x00a3e72be9ac53edULL, + 0x00efcde1629170c2ULL, 0x0004225fe91ef535ULL, + 0x0088049fc73dfda7ULL, 0x004abc74857e1288ULL, + 0x0024e2434657317cULL, 0x00d98cb3d3e5543cULL)}, + }}, {{ + {FIELD_LITERAL(0x00b4b53eab6bdb19ULL, 0x009b22d8b43711d0ULL, + 0x00d948b9d961785dULL, 0x00cb167b6f279eadULL, + 0x00191de3a678e1c9ULL, 0x00d9dd9511095c2eULL, + 0x00f284324cd43067ULL, 0x00ed74fa535151ddULL)}, + {FIELD_LITERAL(0x007e32c049b5c477ULL, 0x009d2bfdbd9bcfd8ULL, + 0x00636e93045938c6ULL, 0x007fde4af7687298ULL, + 0x0046a5184fafa5d3ULL, 0x0079b1e7f13a359bULL, + 0x00875adf1fb927d6ULL, 0x00333e21c61bcad2ULL)}, + {FIELD_LITERAL(0x00048014f73d8b8dULL, 0x0075684aa0966388ULL, + 0x0092be7df06dc47cULL, 0x0097cebcd0f5568aULL, + 0x005a7004d9c4c6a9ULL, 0x00b0ecbb659924c7ULL, + 0x00d90332dd492a7cULL, 0x0057fc14df11493dULL)}, + }}, {{ + {FIELD_LITERAL(0x0008ed8ea0ad95beULL, 0x0041d324b9709645ULL, + 0x00e25412257a19b4ULL, 0x0058df9f3423d8d2ULL, + 0x00a9ab20def71304ULL, 0x009ae0dbf8ac4a81ULL, + 0x00c9565977e4392aULL, 0x003c9269444baf55ULL)}, + {FIELD_LITERAL(0x007df6cbb926830bULL, 0x00d336058ae37865ULL, + 0x007af47dac696423ULL, 0x0048d3011ec64ac8ULL, + 0x006b87666e40049fULL, 0x0036a2e0e51303d7ULL, + 0x00ba319bd79dbc55ULL, 0x003e2737ecc94f53ULL)}, + {FIELD_LITERAL(0x00d296ff726272d9ULL, 0x00f6d097928fcf57ULL, + 0x00e0e616a55d7013ULL, 0x00deaf454ed9eac7ULL, + 0x0073a56bedef4d92ULL, 0x006ccfdf6fc92e19ULL, + 0x009d1ee1371a7218ULL, 0x00ee3c2ee4462d80ULL)}, + }}, {{ + {FIELD_LITERAL(0x00437bce9bccdf9dULL, 0x00e0c8e2f85dc0a3ULL, + 0x00c91a7073995a19ULL, 0x00856ec9fe294559ULL, + 0x009e4b33394b156eULL, 0x00e245b0dc497e5cULL, + 0x006a54e687eeaeffULL, 0x00f1cd1cd00fdb7cULL)}, + {FIELD_LITERAL(0x008132ae5c5d8cd1ULL, 0x00121d68324a1d9fULL, + 0x00d6be9dafcb8c76ULL, 0x00684d9070edf745ULL, + 0x00519fbc96d7448eULL, 0x00388182fdc1f27eULL, + 0x000235baed41f158ULL, 0x00bf6cf6f1a1796aULL)}, + {FIELD_LITERAL(0x002adc4b4d148219ULL, 0x003084ada0d3a90aULL, + 0x0046de8aab0f2e4eULL, 0x00452d342a67b5fdULL, + 0x00d4b50f01d4de21ULL, 0x00db6d9fc0cefb79ULL, + 0x008c184c86a462cdULL, 0x00e17c83764d42daULL)}, + }}, {{ + {FIELD_LITERAL(0x007b2743b9a1e01aULL, 0x007847ffd42688c4ULL, + 0x006c7844d610a316ULL, 0x00f0cb8b250aa4b0ULL, + 0x00a19060143b3ae6ULL, 0x0014eb10b77cfd80ULL, + 0x000170905729dd06ULL, 0x00063b5b9cd72477ULL)}, + {FIELD_LITERAL(0x00ce382dc7993d92ULL, 0x00021153e938b4c8ULL, + 0x00096f7567f48f51ULL, 0x0058f81ddfe4b0d5ULL, + 0x00cc379a56b355c7ULL, 0x002c760770d3e819ULL, + 0x00ee22d1d26e5a40ULL, 0x00de6d93d5b082d7ULL)}, + {FIELD_LITERAL(0x000a91a42c52e056ULL, 0x00185f6b77fce7eaULL, + 0x000803c51962f6b5ULL, 0x0022528582ba563dULL, + 0x0043f8040e9856d6ULL, 0x0085a29ec81fb860ULL, + 0x005f9a611549f5ffULL, 0x00c1f974ecbd4b06ULL)}, + }}, {{ + {FIELD_LITERAL(0x005b64c6fd65ec97ULL, 0x00c1fdd7f877bc7fULL, + 0x000d9cc6c89f841cULL, 0x005c97b7f1aff9adULL, + 0x0075e3c61475d47eULL, 0x001ecb1ba8153011ULL, + 0x00fe7f1c8d71d40dULL, 0x003fa9757a229832ULL)}, + {FIELD_LITERAL(0x00ffc5c89d2b0cbaULL, 0x00d363d42e3e6fc3ULL, + 0x0019a1a0118e2e8aULL, 0x00f7baeff48882e1ULL, + 0x001bd5af28c6b514ULL, 0x0055476ca2253cb2ULL, + 0x00d8eb1977e2ddf3ULL, 0x00b173b1adb228a1ULL)}, + {FIELD_LITERAL(0x00f2cb99dd0ad707ULL, 0x00e1e08b6859ddd8ULL, + 0x000008f2d0650bccULL, 0x00d7ed392f8615c3ULL, + 0x00976750a94da27fULL, 0x003e83bb0ecb69baULL, + 0x00df8e8d15c14ac6ULL, 0x00f9f7174295d9c2ULL)}, + }}, {{ + {FIELD_LITERAL(0x00f11cc8e0e70bcbULL, 0x00e5dc689974e7ddULL, + 0x0014e409f9ee5870ULL, 0x00826e6689acbd63ULL, + 0x008a6f4e3d895d88ULL, 0x00b26a8da41fd4adULL, + 0x000fb7723f83efd7ULL, 0x009c749db0a5f6c3ULL)}, + {FIELD_LITERAL(0x002389319450f9baULL, 0x003677f31aa1250aULL, + 0x0092c3db642f38cbULL, 0x00f8b64c0dfc9773ULL, + 0x00cd49fe3505b795ULL, 0x0068105a4090a510ULL, + 0x00df0ba2072a8bb6ULL, 0x00eb396143afd8beULL)}, + {FIELD_LITERAL(0x00a0d4ecfb24cdffULL, 0x00ddaf8008ba6479ULL, + 0x00f0b3e36d4b0f44ULL, 0x003734bd3af1f146ULL, + 0x00b87e2efc75527eULL, 0x00d230df55ddab50ULL, + 0x002613257ae56c1dULL, 0x00bc0946d135934dULL)}, + }}, {{ + {FIELD_LITERAL(0x00468711bd994651ULL, 0x0033108fa67561bfULL, + 0x0089d760192a54b4ULL, 0x00adc433de9f1871ULL, + 0x000467d05f36e050ULL, 0x007847e0f0579f7fULL, + 0x00a2314ad320052dULL, 0x00b3a93649f0b243ULL)}, + {FIELD_LITERAL(0x0067f8f0c4fe26c9ULL, 0x0079c4a3cc8f67b9ULL, + 0x0082b1e62f23550dULL, 0x00f2d409caefd7f5ULL, + 0x0080e67dcdb26e81ULL, 0x0087ae993ea1f98aULL, + 0x00aa108becf61d03ULL, 0x001acf11efb608a3ULL)}, + {FIELD_LITERAL(0x008225febbab50d9ULL, 0x00f3b605e4dd2083ULL, + 0x00a32b28189e23d2ULL, 0x00d507e5e5eb4c97ULL, + 0x005a1a84e302821fULL, 0x0006f54c1c5f08c7ULL, + 0x00a347c8cb2843f0ULL, 0x0009f73e9544bfa5ULL)}, + }}, {{ + {FIELD_LITERAL(0x006c59c9ae744185ULL, 0x009fc32f1b4282cdULL, + 0x004d6348ca59b1acULL, 0x00105376881be067ULL, + 0x00af4096013147dcULL, 0x004abfb5a5cb3124ULL, + 0x000d2a7f8626c354ULL, 0x009c6ed568e07431ULL)}, + {FIELD_LITERAL(0x00e828333c297f8bULL, 0x009ef3cf8c3f7e1fULL, + 0x00ab45f8fff31cb9ULL, 0x00c8b4178cb0b013ULL, + 0x00d0c50dd3260a3fULL, 0x0097126ac257f5bcULL, + 0x0042376cc90c705aULL, 0x001d96fdb4a1071eULL)}, + {FIELD_LITERAL(0x00542d44d89ee1a8ULL, 0x00306642e0442d98ULL, + 0x0090853872b87338ULL, 0x002362cbf22dc044ULL, + 0x002c222adff663b8ULL, 0x0067c924495fcb79ULL, + 0x000e621d983c977cULL, 0x00df77a9eccb66fbULL)}, + }}, {{ + {FIELD_LITERAL(0x002809e4bbf1814aULL, 0x00b9e854f9fafb32ULL, + 0x00d35e67c10f7a67ULL, 0x008f1bcb76e748cfULL, + 0x004224d9515687d2ULL, 0x005ba0b774e620c4ULL, + 0x00b5e57db5d54119ULL, 0x00e15babe5683282ULL)}, + {FIELD_LITERAL(0x00832d02369b482cULL, 0x00cba52ff0d93450ULL, + 0x003fa9c908d554dbULL, 0x008d1e357b54122fULL, + 0x00abd91c2dc950c6ULL, 0x007eff1df4c0ec69ULL, + 0x003f6aeb13fb2d31ULL, 0x00002d6179fc5b2cULL)}, + {FIELD_LITERAL(0x0046c9eda81c9c89ULL, 0x00b60cb71c8f62fcULL, + 0x0022f5a683baa558ULL, 0x00f87319fccdf997ULL, + 0x009ca09b51ce6a22ULL, 0x005b12baf4af7d77ULL, + 0x008a46524a1e33e2ULL, 0x00035a77e988be0dULL)}, + }}, {{ + {FIELD_LITERAL(0x00a7efe46a7dbe2fULL, 0x002f66fd55014fe7ULL, + 0x006a428afa1ff026ULL, 0x0056caaa9604ab72ULL, + 0x0033f3bcd7fac8aeULL, 0x00ccb1aa01c86764ULL, + 0x00158d1edf13bf40ULL, 0x009848ee76fcf3b4ULL)}, + {FIELD_LITERAL(0x00a9e7730a819691ULL, 0x00d9cc73c4992b70ULL, + 0x00e299bde067de5aULL, 0x008c314eb705192aULL, + 0x00e7226f17e8a3ccULL, 0x0029dfd956e65a47ULL, + 0x0053a8e839073b12ULL, 0x006f942b2ab1597eULL)}, + {FIELD_LITERAL(0x001c3d780ecd5e39ULL, 0x0094f247fbdcc5feULL, + 0x00d5c786fd527764ULL, 0x00b6f4da74f0db2aULL, + 0x0080f1f8badcd5fcULL, 0x00f36a373ad2e23bULL, + 0x00f804f9f4343bf2ULL, 0x00d1af40ec623982ULL)}, + }}, {{ + {FIELD_LITERAL(0x0082aeace5f1b144ULL, 0x00f68b3108cf4dd3ULL, + 0x00634af01dde3020ULL, 0x000beab5df5c2355ULL, + 0x00e8b790d1b49b0bULL, 0x00e48d15854e36f4ULL, + 0x0040ab2d95f3db9fULL, 0x002711c4ed9e899aULL)}, + {FIELD_LITERAL(0x0039343746531ebeULL, 0x00c8509d835d429dULL, + 0x00e79eceff6b0018ULL, 0x004abfd31e8efce5ULL, + 0x007bbfaaa1e20210ULL, 0x00e3be89c193e179ULL, + 0x001c420f4c31d585ULL, 0x00f414a315bef5aeULL)}, + {FIELD_LITERAL(0x007c296a24990df8ULL, 0x00d5d07525a75588ULL, + 0x00dd8e113e94b7e7ULL, 0x007bbc58febe0cc8ULL, + 0x0029f51af9bfcad3ULL, 0x007e9311ec7ab6f3ULL, + 0x009a884de1676343ULL, 0x0050d5f2dce84be9ULL)}, + }}, {{ + {FIELD_LITERAL(0x005fa020cca2450aULL, 0x00491c29db6416d8ULL, + 0x0037cefe3f9f9a85ULL, 0x003d405230647066ULL, + 0x0049e835f0fdbe89ULL, 0x00feb78ac1a0815cULL, + 0x00828e4b32dc9724ULL, 0x00db84f2dc8d6fd4ULL)}, + {FIELD_LITERAL(0x0098cddc8b39549aULL, 0x006da37e3b05d22cULL, + 0x00ce633cfd4eb3cbULL, 0x00fda288ef526acdULL, + 0x0025338878c5d30aULL, 0x00f34438c4e5a1b4ULL, + 0x00584efea7c310f1ULL, 0x0041a551f1b660adULL)}, + {FIELD_LITERAL(0x00d7f7a8fbd6437aULL, 0x0062872413bf3753ULL, + 0x00ad4bbcb43c584bULL, 0x007fe49be601d7e3ULL, + 0x0077c659789babf4ULL, 0x00eb45fcb06a741bULL, + 0x005ce244913f9708ULL, 0x0088426401736326ULL)}, + }}, {{ + {FIELD_LITERAL(0x007bf562ca768d7cULL, 0x006c1f3a174e387cULL, + 0x00f024b447fee939ULL, 0x007e7af75f01143fULL, + 0x003adb70b4eed89dULL, 0x00e43544021ad79aULL, + 0x0091f7f7042011f6ULL, 0x0093c1a1ee3a0ddcULL)}, + {FIELD_LITERAL(0x00a0b68ec1eb72d2ULL, 0x002c03235c0d45a0ULL, + 0x00553627323fe8c5ULL, 0x006186e94b17af94ULL, + 0x00a9906196e29f14ULL, 0x0025b3aee6567733ULL, + 0x007e0dd840080517ULL, 0x0018eb5801a4ba93ULL)}, + {FIELD_LITERAL(0x00d7fe7017bf6a40ULL, 0x006e3f0624be0c42ULL, + 0x00ffbba205358245ULL, 0x00f9fc2cf8194239ULL, + 0x008d93b37bf15b4eULL, 0x006ddf2e38be8e95ULL, + 0x002b6e79bf5fcff9ULL, 0x00ab355da425e2deULL)}, + }}, {{ + {FIELD_LITERAL(0x00938f97e20be973ULL, 0x0099141a36aaf306ULL, + 0x0057b0ca29e545a1ULL, 0x0085db571f9fbc13ULL, + 0x008b333c554b4693ULL, 0x0043ab6ef3e241cbULL, + 0x0054fb20aa1e5c70ULL, 0x00be0ff852760adfULL)}, + {FIELD_LITERAL(0x003973d8938971d6ULL, 0x002aca26fa80c1f5ULL, + 0x00108af1faa6b513ULL, 0x00daae275d7924e6ULL, + 0x0053634ced721308ULL, 0x00d2355fe0bbd443ULL, + 0x00357612b2d22095ULL, 0x00f9bb9dd4136cf3ULL)}, + {FIELD_LITERAL(0x002bff12cf5e03a5ULL, 0x001bdb1fa8a19cf8ULL, + 0x00c91c6793f84d39ULL, 0x00f869f1b2eba9afULL, + 0x0059bc547dc3236bULL, 0x00d91611d6d38689ULL, + 0x00e062daaa2c0214ULL, 0x00ed3c047cc2bc82ULL)}, + }}, {{ + {FIELD_LITERAL(0x000050d70c32b31aULL, 0x001939d576d437b3ULL, + 0x00d709e598bf9fe6ULL, 0x00a885b34bd2ee9eULL, + 0x00dd4b5c08ab1a50ULL, 0x0091bebd50b55639ULL, + 0x00cf79ff64acdbc6ULL, 0x006067a39d826336ULL)}, + {FIELD_LITERAL(0x0062dd0fb31be374ULL, 0x00fcc96b84c8e727ULL, + 0x003f64f1375e6ae3ULL, 0x0057d9b6dd1af004ULL, + 0x00d6a167b1103c7bULL, 0x00dd28f3180fb537ULL, + 0x004ff27ad7167128ULL, 0x008934c33461f2acULL)}, + {FIELD_LITERAL(0x0065b472b7900043ULL, 0x00ba7efd2ff1064bULL, + 0x000b67d6c4c3020fULL, 0x0012d28469f4e46dULL, + 0x0031c32939703ec7ULL, 0x00b49f0bce133066ULL, + 0x00f7e10416181d47ULL, 0x005c90f51867eeccULL)}, + }}, {{ + {FIELD_LITERAL(0x0051207abd179101ULL, 0x00fc2a5c20d9c5daULL, + 0x00fb9d5f2701b6dfULL, 0x002dd040fdea82b8ULL, + 0x00f163b0738442ffULL, 0x00d9736bd68855b8ULL, + 0x00e0d8e93005e61cULL, 0x00df5a40b3988570ULL)}, + {FIELD_LITERAL(0x0006918f5dfce6dcULL, 0x00d4bf1c793c57fbULL, + 0x0069a3f649435364ULL, 0x00e89a50e5b0cd6eULL, + 0x00b9f6a237e973afULL, 0x006d4ed8b104e41dULL, + 0x00498946a3924cd2ULL, 0x00c136ec5ac9d4f7ULL)}, + {FIELD_LITERAL(0x0011a9c290ac5336ULL, 0x002b9a2d4a6a6533ULL, + 0x009a8a68c445d937ULL, 0x00361b27b07e5e5cULL, + 0x003c043b1755b974ULL, 0x00b7eb66cf1155eeULL, + 0x0077af5909eefff2ULL, 0x0098f609877cc806ULL)}, + }}, {{ + {FIELD_LITERAL(0x00ab13af436bf8f4ULL, 0x000bcf0a0dac8574ULL, + 0x00d50c864f705045ULL, 0x00c40e611debc842ULL, + 0x0085010489bd5caaULL, 0x007c5050acec026fULL, + 0x00f67d943c8da6d1ULL, 0x00de1da0278074c6ULL)}, + {FIELD_LITERAL(0x00b373076597455fULL, 0x00e83f1af53ac0f5ULL, + 0x0041f63c01dc6840ULL, 0x0097dea19b0c6f4bULL, + 0x007f9d63b4c1572cULL, 0x00e692d492d0f5f0ULL, + 0x00cbcb392e83b4adULL, 0x0069c0f39ed9b1a8ULL)}, + {FIELD_LITERAL(0x00861030012707c9ULL, 0x009fbbdc7fd4aafbULL, + 0x008f591d6b554822ULL, 0x00df08a41ea18adeULL, + 0x009d7d83e642abeaULL, 0x0098c71bda3b78ffULL, + 0x0022c89e7021f005ULL, 0x0044d29a3fe1e3c4ULL)}, + }}, {{ + {FIELD_LITERAL(0x00e748cd7b5c52f2ULL, 0x00ea9df883f89cc3ULL, + 0x0018970df156b6c7ULL, 0x00c5a46c2a33a847ULL, + 0x00cbde395e32aa09ULL, 0x0072474ebb423140ULL, + 0x00fb00053086a23dULL, 0x001dafcfe22d4e1fULL)}, + {FIELD_LITERAL(0x00c903ee6d825540ULL, 0x00add6c4cf98473eULL, + 0x007636efed4227f1ULL, 0x00905124ae55e772ULL, + 0x00e6b38fab12ed53ULL, 0x0045e132b863fe55ULL, + 0x003974662edb366aULL, 0x00b1787052be8208ULL)}, + {FIELD_LITERAL(0x00a614b00d775c7cULL, 0x00d7c78941cc7754ULL, + 0x00422dd68b5dabc4ULL, 0x00a6110f0167d28bULL, + 0x00685a309c252886ULL, 0x00b439ffd5143660ULL, + 0x003656e29ee7396fULL, 0x00c7c9b9ed5ad854ULL)}, + }}, {{ + {FIELD_LITERAL(0x0040f7e7c5b37bf2ULL, 0x0064e4dc81181bbaULL, + 0x00a8767ae2a366b6ULL, 0x001496b4f90546f2ULL, + 0x002a28493f860441ULL, 0x0021f59513049a3aULL, + 0x00852d369a8b7ee3ULL, 0x00dd2e7d8b7d30a9ULL)}, + {FIELD_LITERAL(0x00006e34a35d9fbcULL, 0x00eee4e48b2f019aULL, + 0x006b344743003a5fULL, 0x00541d514f04a7e3ULL, + 0x00e81f9ee7647455ULL, 0x005e2b916c438f81ULL, + 0x00116f8137b7eff0ULL, 0x009bd3decc7039d1ULL)}, + {FIELD_LITERAL(0x0005d226f434110dULL, 0x00af8288b8ef21d5ULL, + 0x004a7a52ef181c8cULL, 0x00be0b781b4b06deULL, + 0x00e6e3627ded07e1ULL, 0x00e43aa342272b8bULL, + 0x00e86ab424577d84ULL, 0x00fb292c566e35bbULL)}, + }}, {{ + {FIELD_LITERAL(0x00334f5303ea1222ULL, 0x00dfb3dbeb0a5d3eULL, + 0x002940d9592335c1ULL, 0x00706a7a63e8938aULL, + 0x005a533558bc4cafULL, 0x00558e33192022a9ULL, + 0x00970d9faf74c133ULL, 0x002979fcb63493caULL)}, + {FIELD_LITERAL(0x00e38abece3c82abULL, 0x005a51f18a2c7a86ULL, + 0x009dafa2e86d592eULL, 0x00495a62eb688678ULL, + 0x00b79df74c0eb212ULL, 0x0023e8cc78b75982ULL, + 0x005998cb91075e13ULL, 0x00735aa9ba61bc76ULL)}, + {FIELD_LITERAL(0x00d9f7a82ddbe628ULL, 0x00a1fc782889ae0fULL, + 0x0071ffda12d14b66ULL, 0x0037cf4eca7fb3d5ULL, + 0x00c80bc242c58808ULL, 0x0075bf8c2d08c863ULL, + 0x008d41f31afc52a7ULL, 0x00197962ecf38741ULL)}, + }}, {{ + {FIELD_LITERAL(0x006e9f475cccf2eeULL, 0x00454b9cd506430cULL, + 0x00224a4fb79ee479ULL, 0x0062e3347ef0b5e2ULL, + 0x0034fd2a3512232aULL, 0x00b8b3cb0f457046ULL, + 0x00eb20165daa38ecULL, 0x00128eebc2d9c0f7ULL)}, + {FIELD_LITERAL(0x00bfc5fa1e4ea21fULL, 0x00c21d7b6bb892e6ULL, + 0x00cf043f3acf0291ULL, 0x00c13f2f849b3c90ULL, + 0x00d1a97ebef10891ULL, 0x0061e130a445e7feULL, + 0x0019513fdedbf22bULL, 0x001d60c813bff841ULL)}, + {FIELD_LITERAL(0x0019561c7fcf0213ULL, 0x00e3dca6843ebd77ULL, + 0x0068ea95b9ca920eULL, 0x009bdfb70f253595ULL, + 0x00c68f59186aa02aULL, 0x005aee1cca1c3039ULL, + 0x00ab79a8a937a1ceULL, 0x00b9a0e549959e6fULL)}, + }}, {{ + {FIELD_LITERAL(0x00c79e0b6d97dfbdULL, 0x00917c71fd2bc6e8ULL, + 0x00db7529ccfb63d8ULL, 0x00be5be957f17866ULL, + 0x00a9e11fdc2cdac1ULL, 0x007b91a8e1f44443ULL, + 0x00a3065e4057d80fULL, 0x004825f5b8d5f6d4ULL)}, + {FIELD_LITERAL(0x003e4964fa8a8fc8ULL, 0x00f6a1cdbcf41689ULL, + 0x00943cb18fe7fda7ULL, 0x00606dafbf34440aULL, + 0x005d37a86399c789ULL, 0x00e79a2a69417403ULL, + 0x00fe34f7e68b8866ULL, 0x0011f448ed2df10eULL)}, + {FIELD_LITERAL(0x00f1f57efcc1fcc4ULL, 0x00513679117de154ULL, + 0x002e5b5b7c86d8c3ULL, 0x009f6486561f9cfbULL, + 0x00169e74b0170cf7ULL, 0x00900205af4af696ULL, + 0x006acfddb77853f3ULL, 0x00df184c90f31068ULL)}, + }}, {{ + {FIELD_LITERAL(0x00b37396c3320791ULL, 0x00fc7b67175c5783ULL, + 0x00c36d2cd73ecc38ULL, 0x0080ebcc0b328fc5ULL, + 0x0043a5b22b35d35dULL, 0x00466c9f1713c9daULL, + 0x0026ad346dcaa8daULL, 0x007c684e701183a6ULL)}, + {FIELD_LITERAL(0x00fd579ffb691713ULL, 0x00b76af4f81c412dULL, + 0x00f239de96110f82ULL, 0x00e965fb437f0306ULL, + 0x00ca7e9436900921ULL, 0x00e487f1325fa24aULL, + 0x00633907de476380ULL, 0x00721c62ac5b8ea0ULL)}, + {FIELD_LITERAL(0x00c0d54e542eb4f9ULL, 0x004ed657171c8dcfULL, + 0x00b743a4f7c2a39bULL, 0x00fd9f93ed6cc567ULL, + 0x00307fae3113e58bULL, 0x0058aa577c93c319ULL, + 0x00d254556f35b346ULL, 0x00491aada2203f0dULL)}, + }}, {{ + {FIELD_LITERAL(0x00dff3103786ff34ULL, 0x000144553b1f20c3ULL, + 0x0095613baeb930e4ULL, 0x00098058275ea5d4ULL, + 0x007cd1402b046756ULL, 0x0074d74e4d58aee3ULL, + 0x005f93fc343ff69bULL, 0x00873df17296b3b0ULL)}, + {FIELD_LITERAL(0x00c4a1fb48635413ULL, 0x00b5dd54423ad59fULL, + 0x009ff5d53fd24a88ULL, 0x003c98d267fc06a7ULL, + 0x002db7cb20013641ULL, 0x00bd1d6716e191f2ULL, + 0x006dbc8b29094241ULL, 0x0044bbf233dafa2cULL)}, + {FIELD_LITERAL(0x0055838d41f531e6ULL, 0x00bf6a2dd03c81b2ULL, + 0x005827a061c4839eULL, 0x0000de2cbb36aac3ULL, + 0x002efa29d9717478ULL, 0x00f9e928cc8a77baULL, + 0x00c134b458def9efULL, 0x00958a182223fc48ULL)}, + }}, {{ + {FIELD_LITERAL(0x000a9ee23c06881fULL, 0x002c727d3d871945ULL, + 0x00f47d971512d24aULL, 0x00671e816f9ef31aULL, + 0x00883af2cfaad673ULL, 0x00601f98583d6c9aULL, + 0x00b435f5adc79655ULL, 0x00ad87b71c04bff2ULL)}, + {FIELD_LITERAL(0x007860d99db787cfULL, 0x00fda8983018f4a8ULL, + 0x008c8866bac4743cULL, 0x00ef471f84c82a3fULL, + 0x00abea5976d3b8e7ULL, 0x00714882896cd015ULL, + 0x00b49fae584ddac5ULL, 0x008e33a1a0b69c81ULL)}, + {FIELD_LITERAL(0x007b6ee2c9e8a9ecULL, 0x002455dbbd89d622ULL, + 0x006490cf4eaab038ULL, 0x00d925f6c3081561ULL, + 0x00153b3047de7382ULL, 0x003b421f8bdceb6fULL, + 0x00761a4a5049da78ULL, 0x00980348c5202433ULL)}, + }}, {{ + {FIELD_LITERAL(0x007f8a43da97dd5cULL, 0x00058539c800fc7bULL, + 0x0040f3cf5a28414aULL, 0x00d68dd0d95283d6ULL, + 0x004adce9da90146eULL, 0x00befa41c7d4f908ULL, + 0x007603bc2e3c3060ULL, 0x00bdf360ab3545dbULL)}, + {FIELD_LITERAL(0x00eebfd4e2312cc3ULL, 0x00474b2564e4fc8cULL, + 0x003303ef14b1da9bULL, 0x003c93e0e66beb1dULL, + 0x0013619b0566925aULL, 0x008817c24d901bf3ULL, + 0x00b62bd8898d218bULL, 0x0075a7716f1e88a2ULL)}, + {FIELD_LITERAL(0x0009218da1e6890fULL, 0x0026907f5fd02575ULL, + 0x004dabed5f19d605ULL, 0x003abf181870249dULL, + 0x00b52fd048cc92c4ULL, 0x00b6dd51e415a5c5ULL, + 0x00d9eb82bd2b4014ULL, 0x002c865a43b46b43ULL)}, + }}, {{ + {FIELD_LITERAL(0x0070047189452f4cULL, 0x00f7ad12e1ce78d5ULL, + 0x00af1ba51ec44a8bULL, 0x005f39f63e667cd6ULL, + 0x00058eac4648425eULL, 0x00d7fdab42bea03bULL, + 0x0028576a5688de15ULL, 0x00af973209e77c10ULL)}, + {FIELD_LITERAL(0x00c338b915d8fef0ULL, 0x00a893292045c39aULL, + 0x0028ab4f2eba6887ULL, 0x0060743cb519fd61ULL, + 0x0006213964093ac0ULL, 0x007c0b7a43f6266dULL, + 0x008e3557c4fa5bdaULL, 0x002da976de7b8d9dULL)}, + {FIELD_LITERAL(0x0048729f8a8b6dcdULL, 0x00fe23b85cc4d323ULL, + 0x00e7384d16e4db0eULL, 0x004a423970678942ULL, + 0x00ec0b763345d4baULL, 0x00c477b9f99ed721ULL, + 0x00c29dad3777b230ULL, 0x001c517b466f7df6ULL)}, + }}, {{ + {FIELD_LITERAL(0x006366c380f7b574ULL, 0x001c7d1f09ff0438ULL, + 0x003e20a7301f5b22ULL, 0x00d3efb1916d28f6ULL, + 0x0049f4f81060ce83ULL, 0x00c69d91ea43ced1ULL, + 0x002b6f3e5cd269edULL, 0x005b0fb22ce9ec65ULL)}, + {FIELD_LITERAL(0x00aa2261022d883fULL, 0x00ebcca4548010acULL, + 0x002528512e28a437ULL, 0x0070ca7676b66082ULL, + 0x0084bda170f7c6d3ULL, 0x00581b4747c9b8bbULL, + 0x005c96a01061c7e2ULL, 0x00fb7c4a362b5273ULL)}, + {FIELD_LITERAL(0x00c30020eb512d02ULL, 0x0060f288283a4d26ULL, + 0x00b7ed13becde260ULL, 0x0075ebb74220f6e9ULL, + 0x00701079fcfe8a1fULL, 0x001c28fcdff58938ULL, + 0x002e4544b8f4df6bULL, 0x0060c5bc4f1a7d73ULL)}, + }}, {{ + {FIELD_LITERAL(0x00ae307cf069f701ULL, 0x005859f222dd618bULL, + 0x00212d6c46ec0b0dULL, 0x00a0fe4642afb62dULL, + 0x00420d8e4a0a8903ULL, 0x00a80ff639bdf7b0ULL, + 0x0019bee1490b5d8eULL, 0x007439e4b9c27a86ULL)}, + {FIELD_LITERAL(0x00a94700032a093fULL, 0x0076e96c225216e7ULL, + 0x00a63a4316e45f91ULL, 0x007d8bbb4645d3b2ULL, + 0x00340a6ff22793ebULL, 0x006f935d4572aeb7ULL, + 0x00b1fb69f00afa28ULL, 0x009e8f3423161ed3ULL)}, + {FIELD_LITERAL(0x009ef49c6b5ced17ULL, 0x00a555e6269e9f0aULL, + 0x007e6f1d79ec73b5ULL, 0x009ac78695a32ac4ULL, + 0x0001d77fbbcd5682ULL, 0x008cea1fee0aaeedULL, + 0x00f42bea82a53462ULL, 0x002e46ab96cafcc9ULL)}, + }}, {{ + {FIELD_LITERAL(0x0051cfcc5885377aULL, 0x00dce566cb1803caULL, + 0x00430c7643f2c7d4ULL, 0x00dce1a1337bdcc0ULL, + 0x0010d5bd7283c128ULL, 0x003b1b547f9b46feULL, + 0x000f245e37e770abULL, 0x007b72511f022b37ULL)}, + {FIELD_LITERAL(0x0060db815bc4786cULL, 0x006fab25beedc434ULL, + 0x00c610d06084797cULL, 0x000c48f08537bec0ULL, + 0x0031aba51c5b93daULL, 0x007968fa6e01f347ULL, + 0x0030070da52840c6ULL, 0x00c043c225a4837fULL)}, + {FIELD_LITERAL(0x001bcfd00649ee93ULL, 0x006dceb47e2a0fd5ULL, + 0x00f2cebda0cf8fd0ULL, 0x00b6b9d9d1fbdec3ULL, + 0x00815262e6490611ULL, 0x00ef7f5ce3176760ULL, + 0x00e49cd0c998d58bULL, 0x005fc6cc269ba57cULL)}, + }}, {{ + {FIELD_LITERAL(0x008940211aa0d633ULL, 0x00addae28136571dULL, + 0x00d68fdbba20d673ULL, 0x003bc6129bc9e21aULL, + 0x000346cf184ebe9aULL, 0x0068774d741ebc7fULL, + 0x0019d5e9e6966557ULL, 0x0003cbd7f981b651ULL)}, + {FIELD_LITERAL(0x004a2902926f8d3fULL, 0x00ad79b42637ab75ULL, + 0x0088f60b90f2d4e8ULL, 0x0030f54ef0e398c4ULL, + 0x00021dc9bf99681eULL, 0x007ebf66fde74ee3ULL, + 0x004ade654386e9a4ULL, 0x00e7485066be4c27ULL)}, + {FIELD_LITERAL(0x00445f1263983be0ULL, 0x004cf371dda45e6aULL, + 0x00744a89d5a310e7ULL, 0x001f20ce4f904833ULL, + 0x00e746edebe66e29ULL, 0x000912ab1f6c153dULL, + 0x00f61d77d9b2444cULL, 0x0001499cd6647610ULL)}, }} } }; @@ -1063,421 +1063,421 @@ const struct curve448_precomputed_s *ossl_curve448_precomputed_base static const niels_t curve448_wnaf_base_table[32] = { {{ - {FIELD_LITERAL(0x00303cda6feea532, 0x00860f1d5a3850e4, - 0x00226b9fa4728ccd, 0x00e822938a0a0c0c, - 0x00263a61c9ea9216, 0x001204029321b828, - 0x006a468360983c65, 0x0002846f0a782143)}, - {FIELD_LITERAL(0x00303cda6feea532, 0x00860f1d5a3850e4, - 0x00226b9fa4728ccd, 0x006822938a0a0c0c, - 0x00263a61c9ea9215, 0x001204029321b828, - 0x006a468360983c65, 0x0082846f0a782143)}, - {FIELD_LITERAL(0x00ef8e22b275198d, 0x00b0eb141a0b0e8b, - 0x001f6789da3cb38c, 0x006d2ff8ed39073e, - 0x00610bdb69a167f3, 0x00571f306c9689b4, - 0x00f557e6f84b2df8, 0x002affd38b2c86db)}, + {FIELD_LITERAL(0x00303cda6feea532ULL, 0x00860f1d5a3850e4ULL, + 0x00226b9fa4728ccdULL, 0x00e822938a0a0c0cULL, + 0x00263a61c9ea9216ULL, 0x001204029321b828ULL, + 0x006a468360983c65ULL, 0x0002846f0a782143ULL)}, + {FIELD_LITERAL(0x00303cda6feea532ULL, 0x00860f1d5a3850e4ULL, + 0x00226b9fa4728ccdULL, 0x006822938a0a0c0cULL, + 0x00263a61c9ea9215ULL, 0x001204029321b828ULL, + 0x006a468360983c65ULL, 0x0082846f0a782143ULL)}, + {FIELD_LITERAL(0x00ef8e22b275198dULL, 0x00b0eb141a0b0e8bULL, + 0x001f6789da3cb38cULL, 0x006d2ff8ed39073eULL, + 0x00610bdb69a167f3ULL, 0x00571f306c9689b4ULL, + 0x00f557e6f84b2df8ULL, 0x002affd38b2c86dbULL)}, }}, {{ - {FIELD_LITERAL(0x00cea0fc8d2e88b5, 0x00821612d69f1862, - 0x0074c283b3e67522, 0x005a195ba05a876d, - 0x000cddfe557feea4, 0x008046c795bcc5e5, - 0x00540969f4d6e119, 0x00d27f96d6b143d5)}, - {FIELD_LITERAL(0x000c3b1019d474e8, 0x00e19533e4952284, - 0x00cc9810ba7c920a, 0x00f103d2785945ac, - 0x00bfa5696cc69b34, 0x00a8d3d51e9ca839, - 0x005623cb459586b9, 0x00eae7ce1cd52e9e)}, - {FIELD_LITERAL(0x0005a178751dd7d8, 0x002cc3844c69c42f, - 0x00acbfe5efe10539, 0x009c20f43431a65a, - 0x008435d96374a7b3, 0x009ee57566877bd3, - 0x0044691725ed4757, 0x001e87bb2fe2c6b2)}, + {FIELD_LITERAL(0x00cea0fc8d2e88b5ULL, 0x00821612d69f1862ULL, + 0x0074c283b3e67522ULL, 0x005a195ba05a876dULL, + 0x000cddfe557feea4ULL, 0x008046c795bcc5e5ULL, + 0x00540969f4d6e119ULL, 0x00d27f96d6b143d5ULL)}, + {FIELD_LITERAL(0x000c3b1019d474e8ULL, 0x00e19533e4952284ULL, + 0x00cc9810ba7c920aULL, 0x00f103d2785945acULL, + 0x00bfa5696cc69b34ULL, 0x00a8d3d51e9ca839ULL, + 0x005623cb459586b9ULL, 0x00eae7ce1cd52e9eULL)}, + {FIELD_LITERAL(0x0005a178751dd7d8ULL, 0x002cc3844c69c42fULL, + 0x00acbfe5efe10539ULL, 0x009c20f43431a65aULL, + 0x008435d96374a7b3ULL, 0x009ee57566877bd3ULL, + 0x0044691725ed4757ULL, 0x001e87bb2fe2c6b2ULL)}, }}, {{ - {FIELD_LITERAL(0x000cedc4debf7a04, 0x002ffa45000470ac, - 0x002e9f9678201915, 0x0017da1208c4fe72, - 0x007d558cc7d656cb, 0x0037a827287cf289, - 0x00142472d3441819, 0x009c21f166cf8dd1)}, - {FIELD_LITERAL(0x003ef83af164b2f2, 0x000949a5a0525d0d, - 0x00f4498186cac051, 0x00e77ac09ef126d2, - 0x0073ae0b2c9296e9, 0x001c163f6922e3ed, - 0x0062946159321bea, 0x00cfb79b22990b39)}, - {FIELD_LITERAL(0x00b001431ca9e654, 0x002d7e5eabcc9a3a, - 0x0052e8114c2f6747, 0x0079ac4f94487f92, - 0x00bffd919b5d749c, 0x00261f92ad15e620, - 0x00718397b7a97895, 0x00c1443e6ebbc0c4)}, + {FIELD_LITERAL(0x000cedc4debf7a04ULL, 0x002ffa45000470acULL, + 0x002e9f9678201915ULL, 0x0017da1208c4fe72ULL, + 0x007d558cc7d656cbULL, 0x0037a827287cf289ULL, + 0x00142472d3441819ULL, 0x009c21f166cf8dd1ULL)}, + {FIELD_LITERAL(0x003ef83af164b2f2ULL, 0x000949a5a0525d0dULL, + 0x00f4498186cac051ULL, 0x00e77ac09ef126d2ULL, + 0x0073ae0b2c9296e9ULL, 0x001c163f6922e3edULL, + 0x0062946159321beaULL, 0x00cfb79b22990b39ULL)}, + {FIELD_LITERAL(0x00b001431ca9e654ULL, 0x002d7e5eabcc9a3aULL, + 0x0052e8114c2f6747ULL, 0x0079ac4f94487f92ULL, + 0x00bffd919b5d749cULL, 0x00261f92ad15e620ULL, + 0x00718397b7a97895ULL, 0x00c1443e6ebbc0c4ULL)}, }}, {{ - {FIELD_LITERAL(0x00eacd90c1e0a049, 0x008977935b149fbe, - 0x0004cb9ba11c93dc, 0x009fbd5b3470844d, - 0x004bc18c9bfc22cf, 0x0057679a991839f3, - 0x00ef15b76fb4092e, 0x0074a5173a225041)}, - {FIELD_LITERAL(0x003f5f9d7ec4777b, 0x00ab2e733c919c94, - 0x001bb6c035245ae5, 0x00a325a49a883630, - 0x0033e9a9ea3cea2f, 0x00e442a1eaa0e844, - 0x00b2116d5b0e71b8, 0x00c16abed6d64047)}, - {FIELD_LITERAL(0x00c560b5ed051165, 0x001945adc5d65094, - 0x00e221865710f910, 0x00cc12bc9e9b8ceb, - 0x004faa9518914e35, 0x0017476d89d42f6d, - 0x00b8f637c8fa1c8b, 0x0088c7d2790864b8)}, + {FIELD_LITERAL(0x00eacd90c1e0a049ULL, 0x008977935b149fbeULL, + 0x0004cb9ba11c93dcULL, 0x009fbd5b3470844dULL, + 0x004bc18c9bfc22cfULL, 0x0057679a991839f3ULL, + 0x00ef15b76fb4092eULL, 0x0074a5173a225041ULL)}, + {FIELD_LITERAL(0x003f5f9d7ec4777bULL, 0x00ab2e733c919c94ULL, + 0x001bb6c035245ae5ULL, 0x00a325a49a883630ULL, + 0x0033e9a9ea3cea2fULL, 0x00e442a1eaa0e844ULL, + 0x00b2116d5b0e71b8ULL, 0x00c16abed6d64047ULL)}, + {FIELD_LITERAL(0x00c560b5ed051165ULL, 0x001945adc5d65094ULL, + 0x00e221865710f910ULL, 0x00cc12bc9e9b8cebULL, + 0x004faa9518914e35ULL, 0x0017476d89d42f6dULL, + 0x00b8f637c8fa1c8bULL, 0x0088c7d2790864b8ULL)}, }}, {{ - {FIELD_LITERAL(0x00ef7eafc1c69be6, 0x0085d3855778fbea, - 0x002c8d5b450cb6f5, 0x004e77de5e1e7fec, - 0x0047c057893abded, 0x001b430b85d51e16, - 0x00965c7b45640c3c, 0x00487b2bb1162b97)}, - {FIELD_LITERAL(0x0099c73a311beec2, 0x00a3eff38d8912ad, - 0x002efa9d1d7e8972, 0x00f717ae1e14d126, - 0x002833f795850c8b, 0x0066c12ad71486bd, - 0x00ae9889da4820eb, 0x00d6044309555c08)}, - {FIELD_LITERAL(0x004b1c5283d15e41, 0x00669d8ea308ff75, - 0x0004390233f762a1, 0x00e1d67b83cb6cec, - 0x003eebaa964c78b1, 0x006b0aff965eb664, - 0x00b313d4470bdc37, 0x008814ffcb3cb9d8)}, + {FIELD_LITERAL(0x00ef7eafc1c69be6ULL, 0x0085d3855778fbeaULL, + 0x002c8d5b450cb6f5ULL, 0x004e77de5e1e7fecULL, + 0x0047c057893abdedULL, 0x001b430b85d51e16ULL, + 0x00965c7b45640c3cULL, 0x00487b2bb1162b97ULL)}, + {FIELD_LITERAL(0x0099c73a311beec2ULL, 0x00a3eff38d8912adULL, + 0x002efa9d1d7e8972ULL, 0x00f717ae1e14d126ULL, + 0x002833f795850c8bULL, 0x0066c12ad71486bdULL, + 0x00ae9889da4820ebULL, 0x00d6044309555c08ULL)}, + {FIELD_LITERAL(0x004b1c5283d15e41ULL, 0x00669d8ea308ff75ULL, + 0x0004390233f762a1ULL, 0x00e1d67b83cb6cecULL, + 0x003eebaa964c78b1ULL, 0x006b0aff965eb664ULL, + 0x00b313d4470bdc37ULL, 0x008814ffcb3cb9d8ULL)}, }}, {{ - {FIELD_LITERAL(0x009724b8ce68db70, 0x007678b5ed006f3d, - 0x00bdf4b89c0abd73, 0x00299748e04c7c6d, - 0x00ddd86492c3c977, 0x00c5a7febfa30a99, - 0x00ed84715b4b02bb, 0x00319568adf70486)}, - {FIELD_LITERAL(0x0070ff2d864de5bb, 0x005a37eeb637ee95, - 0x0033741c258de160, 0x00e6ca5cb1988f46, - 0x001ceabd92a24661, 0x0030957bd500fe40, - 0x001c3362afe912c5, 0x005187889f678bd2)}, - {FIELD_LITERAL(0x0086835fc62bbdc7, 0x009c3516ca4910a1, - 0x00956c71f8d00783, 0x0095c78fcf63235f, - 0x00fc7ff6ba05c222, 0x00cdd8b3f8d74a52, - 0x00ac5ae16de8256e, 0x00e9d4be8ed48624)}, + {FIELD_LITERAL(0x009724b8ce68db70ULL, 0x007678b5ed006f3dULL, + 0x00bdf4b89c0abd73ULL, 0x00299748e04c7c6dULL, + 0x00ddd86492c3c977ULL, 0x00c5a7febfa30a99ULL, + 0x00ed84715b4b02bbULL, 0x00319568adf70486ULL)}, + {FIELD_LITERAL(0x0070ff2d864de5bbULL, 0x005a37eeb637ee95ULL, + 0x0033741c258de160ULL, 0x00e6ca5cb1988f46ULL, + 0x001ceabd92a24661ULL, 0x0030957bd500fe40ULL, + 0x001c3362afe912c5ULL, 0x005187889f678bd2ULL)}, + {FIELD_LITERAL(0x0086835fc62bbdc7ULL, 0x009c3516ca4910a1ULL, + 0x00956c71f8d00783ULL, 0x0095c78fcf63235fULL, + 0x00fc7ff6ba05c222ULL, 0x00cdd8b3f8d74a52ULL, + 0x00ac5ae16de8256eULL, 0x00e9d4be8ed48624ULL)}, }}, {{ - {FIELD_LITERAL(0x00c0ce11405df2d8, 0x004e3f37b293d7b6, - 0x002410172e1ac6db, 0x00b8dbff4bf8143d, - 0x003a7b409d56eb66, 0x003e0f6a0dfef9af, - 0x0081c4e4d3645be1, 0x00ce76076b127623)}, - {FIELD_LITERAL(0x00f6ee0f98974239, 0x0042d89af07d3a4f, - 0x00846b7fe84346b5, 0x006a21fc6a8d39a1, - 0x00ac8bc2541ff2d9, 0x006d4e2a77732732, - 0x009a39b694cc3f2f, 0x0085c0aa2a404c8f)}, - {FIELD_LITERAL(0x00b261101a218548, 0x00c1cae96424277b, - 0x00869da0a77dd268, 0x00bc0b09f8ec83ea, - 0x00d61027f8e82ba9, 0x00aa4c85999dce67, - 0x00eac3132b9f3fe1, 0x00fb9b0cf1c695d2)}, + {FIELD_LITERAL(0x00c0ce11405df2d8ULL, 0x004e3f37b293d7b6ULL, + 0x002410172e1ac6dbULL, 0x00b8dbff4bf8143dULL, + 0x003a7b409d56eb66ULL, 0x003e0f6a0dfef9afULL, + 0x0081c4e4d3645be1ULL, 0x00ce76076b127623ULL)}, + {FIELD_LITERAL(0x00f6ee0f98974239ULL, 0x0042d89af07d3a4fULL, + 0x00846b7fe84346b5ULL, 0x006a21fc6a8d39a1ULL, + 0x00ac8bc2541ff2d9ULL, 0x006d4e2a77732732ULL, + 0x009a39b694cc3f2fULL, 0x0085c0aa2a404c8fULL)}, + {FIELD_LITERAL(0x00b261101a218548ULL, 0x00c1cae96424277bULL, + 0x00869da0a77dd268ULL, 0x00bc0b09f8ec83eaULL, + 0x00d61027f8e82ba9ULL, 0x00aa4c85999dce67ULL, + 0x00eac3132b9f3fe1ULL, 0x00fb9b0cf1c695d2ULL)}, }}, {{ - {FIELD_LITERAL(0x0043079295512f0d, 0x0046a009861758e0, - 0x003ee2842a807378, 0x0034cc9d1298e4fa, - 0x009744eb4d31b3ee, 0x00afacec96650cd0, - 0x00ac891b313761ae, 0x00e864d6d26e708a)}, - {FIELD_LITERAL(0x00a84d7c8a23b491, 0x0088e19aa868b27f, - 0x0005986d43e78ce9, 0x00f28012f0606d28, - 0x0017ded7e10249b3, 0x005ed4084b23af9b, - 0x00b9b0a940564472, 0x00ad9056cceeb1f4)}, - {FIELD_LITERAL(0x00db91b357fe755e, 0x00a1aa544b15359c, - 0x00af4931a0195574, 0x007686124fe11aef, - 0x00d1ead3c7b9ef7e, 0x00aaf5fc580f8c15, - 0x00e727be147ee1ec, 0x003c61c1e1577b86)}, + {FIELD_LITERAL(0x0043079295512f0dULL, 0x0046a009861758e0ULL, + 0x003ee2842a807378ULL, 0x0034cc9d1298e4faULL, + 0x009744eb4d31b3eeULL, 0x00afacec96650cd0ULL, + 0x00ac891b313761aeULL, 0x00e864d6d26e708aULL)}, + {FIELD_LITERAL(0x00a84d7c8a23b491ULL, 0x0088e19aa868b27fULL, + 0x0005986d43e78ce9ULL, 0x00f28012f0606d28ULL, + 0x0017ded7e10249b3ULL, 0x005ed4084b23af9bULL, + 0x00b9b0a940564472ULL, 0x00ad9056cceeb1f4ULL)}, + {FIELD_LITERAL(0x00db91b357fe755eULL, 0x00a1aa544b15359cULL, + 0x00af4931a0195574ULL, 0x007686124fe11aefULL, + 0x00d1ead3c7b9ef7eULL, 0x00aaf5fc580f8c15ULL, + 0x00e727be147ee1ecULL, 0x003c61c1e1577b86ULL)}, }}, {{ - {FIELD_LITERAL(0x009d3fca983220cf, 0x00cd11acbc853dc4, - 0x0017590409d27f1d, 0x00d2176698082802, - 0x00fa01251b2838c8, 0x00dd297a0d9b51c6, - 0x00d76c92c045820a, 0x00534bc7c46c9033)}, - {FIELD_LITERAL(0x0080ed9bc9b07338, 0x00fceac7745d2652, - 0x008a9d55f5f2cc69, 0x0096ce72df301ac5, - 0x00f53232e7974d87, 0x0071728c7ae73947, - 0x0090507602570778, 0x00cb81cfd883b1b2)}, - {FIELD_LITERAL(0x005011aadea373da, 0x003a8578ec896034, - 0x00f20a6535fa6d71, 0x005152d31e5a87cf, - 0x002bac1c8e68ca31, 0x00b0e323db4c1381, - 0x00f1d596b7d5ae25, 0x00eae458097cb4e0)}, + {FIELD_LITERAL(0x009d3fca983220cfULL, 0x00cd11acbc853dc4ULL, + 0x0017590409d27f1dULL, 0x00d2176698082802ULL, + 0x00fa01251b2838c8ULL, 0x00dd297a0d9b51c6ULL, + 0x00d76c92c045820aULL, 0x00534bc7c46c9033ULL)}, + {FIELD_LITERAL(0x0080ed9bc9b07338ULL, 0x00fceac7745d2652ULL, + 0x008a9d55f5f2cc69ULL, 0x0096ce72df301ac5ULL, + 0x00f53232e7974d87ULL, 0x0071728c7ae73947ULL, + 0x0090507602570778ULL, 0x00cb81cfd883b1b2ULL)}, + {FIELD_LITERAL(0x005011aadea373daULL, 0x003a8578ec896034ULL, + 0x00f20a6535fa6d71ULL, 0x005152d31e5a87cfULL, + 0x002bac1c8e68ca31ULL, 0x00b0e323db4c1381ULL, + 0x00f1d596b7d5ae25ULL, 0x00eae458097cb4e0ULL)}, }}, {{ - {FIELD_LITERAL(0x00920ac80f9b0d21, 0x00f80f7f73401246, - 0x0086d37849b557d6, 0x0002bd4b317b752e, - 0x00b26463993a42bb, 0x002070422a73b129, - 0x00341acaa0380cb3, 0x00541914dd66a1b2)}, - {FIELD_LITERAL(0x00c1513cd66abe8c, 0x000139e01118944d, - 0x0064abbcb8080bbb, 0x00b3b08202473142, - 0x00c629ef25da2403, 0x00f0aec3310d9b7f, - 0x0050b2227472d8cd, 0x00f6c8a922d41fb4)}, - {FIELD_LITERAL(0x001075ccf26b7b1f, 0x00bb6bb213170433, - 0x00e9491ad262da79, 0x009ef4f48d2d384c, - 0x008992770766f09d, 0x001584396b6b1101, - 0x00af3f8676c9feef, 0x0024603c40269118)}, + {FIELD_LITERAL(0x00920ac80f9b0d21ULL, 0x00f80f7f73401246ULL, + 0x0086d37849b557d6ULL, 0x0002bd4b317b752eULL, + 0x00b26463993a42bbULL, 0x002070422a73b129ULL, + 0x00341acaa0380cb3ULL, 0x00541914dd66a1b2ULL)}, + {FIELD_LITERAL(0x00c1513cd66abe8cULL, 0x000139e01118944dULL, + 0x0064abbcb8080bbbULL, 0x00b3b08202473142ULL, + 0x00c629ef25da2403ULL, 0x00f0aec3310d9b7fULL, + 0x0050b2227472d8cdULL, 0x00f6c8a922d41fb4ULL)}, + {FIELD_LITERAL(0x001075ccf26b7b1fULL, 0x00bb6bb213170433ULL, + 0x00e9491ad262da79ULL, 0x009ef4f48d2d384cULL, + 0x008992770766f09dULL, 0x001584396b6b1101ULL, + 0x00af3f8676c9feefULL, 0x0024603c40269118ULL)}, }}, {{ - {FIELD_LITERAL(0x009dd7b31319527c, 0x001e7ac948d873a9, - 0x00fa54b46ef9673a, 0x0066efb8d5b02fe6, - 0x00754b1d3928aeae, 0x0004262ac72a6f6b, - 0x0079b7d49a6eb026, 0x003126a753540102)}, - {FIELD_LITERAL(0x009666e24f693947, 0x00f714311269d45f, - 0x0010ffac1d0c851c, 0x0066e80c37363497, - 0x00f1f4ad010c60b0, 0x0015c87408470ff7, - 0x00651d5e9c7766a4, 0x008138819d7116de)}, - {FIELD_LITERAL(0x003934b11c57253b, 0x00ef308edf21f46e, - 0x00e54e99c7a16198, 0x0080d57135764e63, - 0x00751c27b946bc24, 0x00dd389ce4e9e129, - 0x00a1a2bfd1cd84dc, 0x002fae73e5149b32)}, + {FIELD_LITERAL(0x009dd7b31319527cULL, 0x001e7ac948d873a9ULL, + 0x00fa54b46ef9673aULL, 0x0066efb8d5b02fe6ULL, + 0x00754b1d3928aeaeULL, 0x0004262ac72a6f6bULL, + 0x0079b7d49a6eb026ULL, 0x003126a753540102ULL)}, + {FIELD_LITERAL(0x009666e24f693947ULL, 0x00f714311269d45fULL, + 0x0010ffac1d0c851cULL, 0x0066e80c37363497ULL, + 0x00f1f4ad010c60b0ULL, 0x0015c87408470ff7ULL, + 0x00651d5e9c7766a4ULL, 0x008138819d7116deULL)}, + {FIELD_LITERAL(0x003934b11c57253bULL, 0x00ef308edf21f46eULL, + 0x00e54e99c7a16198ULL, 0x0080d57135764e63ULL, + 0x00751c27b946bc24ULL, 0x00dd389ce4e9e129ULL, + 0x00a1a2bfd1cd84dcULL, 0x002fae73e5149b32ULL)}, }}, {{ - {FIELD_LITERAL(0x00911657dffb4cdd, 0x00c100b7cc553d06, - 0x00449d075ec467cc, 0x007062100bc64e70, - 0x0043cf86f7bd21e7, 0x00f401dc4b797dea, - 0x005224afb2f62e65, 0x00d1ede3fb5a42be)}, - {FIELD_LITERAL(0x00f2ba36a41aa144, 0x00a0c22d946ee18f, - 0x008aae8ef9a14f99, 0x00eef4d79b19bb36, - 0x008e75ce3d27b1fc, 0x00a65daa03b29a27, - 0x00d9cc83684eb145, 0x009e1ed80cc2ed74)}, - {FIELD_LITERAL(0x00bed953d1997988, 0x00b93ed175a24128, - 0x00871c5963fb6365, 0x00ca2df20014a787, - 0x00f5d9c1d0b34322, 0x00f6f5942818db0a, - 0x004cc091f49c9906, 0x00e8a188a60bff9f)}, + {FIELD_LITERAL(0x00911657dffb4cddULL, 0x00c100b7cc553d06ULL, + 0x00449d075ec467ccULL, 0x007062100bc64e70ULL, + 0x0043cf86f7bd21e7ULL, 0x00f401dc4b797deaULL, + 0x005224afb2f62e65ULL, 0x00d1ede3fb5a42beULL)}, + {FIELD_LITERAL(0x00f2ba36a41aa144ULL, 0x00a0c22d946ee18fULL, + 0x008aae8ef9a14f99ULL, 0x00eef4d79b19bb36ULL, + 0x008e75ce3d27b1fcULL, 0x00a65daa03b29a27ULL, + 0x00d9cc83684eb145ULL, 0x009e1ed80cc2ed74ULL)}, + {FIELD_LITERAL(0x00bed953d1997988ULL, 0x00b93ed175a24128ULL, + 0x00871c5963fb6365ULL, 0x00ca2df20014a787ULL, + 0x00f5d9c1d0b34322ULL, 0x00f6f5942818db0aULL, + 0x004cc091f49c9906ULL, 0x00e8a188a60bff9fULL)}, }}, {{ - {FIELD_LITERAL(0x0032c7762032fae8, 0x00e4087232e0bc21, - 0x00f767344b6e8d85, 0x00bbf369b76c2aa2, - 0x008a1f46c6e1570c, 0x001368cd9780369f, - 0x007359a39d079430, 0x0003646512921434)}, - {FIELD_LITERAL(0x007c4b47ca7c73e7, 0x005396221039734b, - 0x008b64ddf0e45d7e, 0x00bfad5af285e6c2, - 0x008ec711c5b1a1a8, 0x00cf663301237f98, - 0x00917ee3f1655126, 0x004152f337efedd8)}, - {FIELD_LITERAL(0x0007c7edc9305daa, 0x000a6664f273701c, - 0x00f6e78795e200b1, 0x005d05b9ecd2473e, - 0x0014f5f17c865786, 0x00c7fd2d166fa995, - 0x004939a2d8eb80e0, 0x002244ba0942c199)}, + {FIELD_LITERAL(0x0032c7762032fae8ULL, 0x00e4087232e0bc21ULL, + 0x00f767344b6e8d85ULL, 0x00bbf369b76c2aa2ULL, + 0x008a1f46c6e1570cULL, 0x001368cd9780369fULL, + 0x007359a39d079430ULL, 0x0003646512921434ULL)}, + {FIELD_LITERAL(0x007c4b47ca7c73e7ULL, 0x005396221039734bULL, + 0x008b64ddf0e45d7eULL, 0x00bfad5af285e6c2ULL, + 0x008ec711c5b1a1a8ULL, 0x00cf663301237f98ULL, + 0x00917ee3f1655126ULL, 0x004152f337efedd8ULL)}, + {FIELD_LITERAL(0x0007c7edc9305daaULL, 0x000a6664f273701cULL, + 0x00f6e78795e200b1ULL, 0x005d05b9ecd2473eULL, + 0x0014f5f17c865786ULL, 0x00c7fd2d166fa995ULL, + 0x004939a2d8eb80e0ULL, 0x002244ba0942c199ULL)}, }}, {{ - {FIELD_LITERAL(0x00321e767f0262cf, 0x002e57d776caf68e, - 0x00bf2c94814f0437, 0x00c339196acd622f, - 0x001db4cce71e2770, 0x001ded5ddba6eee2, - 0x0078608ab1554c8d, 0x00067fe0ab76365b)}, - {FIELD_LITERAL(0x00f09758e11e3985, 0x00169efdbd64fad3, - 0x00e8889b7d6dacd6, 0x0035cdd58ea88209, - 0x00bcda47586d7f49, 0x003cdddcb2879088, - 0x0016da70187e954b, 0x009556ea2e92aacd)}, - {FIELD_LITERAL(0x008cab16bd1ff897, 0x00b389972cdf753f, - 0x00ea8ed1e46dfdc0, 0x004fe7ef94c589f4, - 0x002b8ae9b805ecf3, 0x0025c08d892874a5, - 0x0023938e98d44c4c, 0x00f759134cabf69c)}, + {FIELD_LITERAL(0x00321e767f0262cfULL, 0x002e57d776caf68eULL, + 0x00bf2c94814f0437ULL, 0x00c339196acd622fULL, + 0x001db4cce71e2770ULL, 0x001ded5ddba6eee2ULL, + 0x0078608ab1554c8dULL, 0x00067fe0ab76365bULL)}, + {FIELD_LITERAL(0x00f09758e11e3985ULL, 0x00169efdbd64fad3ULL, + 0x00e8889b7d6dacd6ULL, 0x0035cdd58ea88209ULL, + 0x00bcda47586d7f49ULL, 0x003cdddcb2879088ULL, + 0x0016da70187e954bULL, 0x009556ea2e92aacdULL)}, + {FIELD_LITERAL(0x008cab16bd1ff897ULL, 0x00b389972cdf753fULL, + 0x00ea8ed1e46dfdc0ULL, 0x004fe7ef94c589f4ULL, + 0x002b8ae9b805ecf3ULL, 0x0025c08d892874a5ULL, + 0x0023938e98d44c4cULL, 0x00f759134cabf69cULL)}, }}, {{ - {FIELD_LITERAL(0x006c2a84678e4b3b, 0x007a194aacd1868f, - 0x00ed0225af424761, 0x00da0a6f293c64b8, - 0x001062ac5c6a7a18, 0x0030f5775a8aeef4, - 0x0002acaad76b7af0, 0x00410b8fd63a579f)}, - {FIELD_LITERAL(0x001ec59db3d9590e, 0x001e9e3f1c3f182d, - 0x0045a9c3ec2cab14, 0x0008198572aeb673, - 0x00773b74068bd167, 0x0012535eaa395434, - 0x0044dba9e3bbb74a, 0x002fba4d3c74bd0e)}, - {FIELD_LITERAL(0x0042bf08fe66922c, 0x003318b8fbb49e8c, - 0x00d75946004aa14c, 0x00f601586b42bf1c, - 0x00c74cf1d912fe66, 0x00abcb36974b30ad, - 0x007eb78720c9d2b8, 0x009f54ab7bd4df85)}, + {FIELD_LITERAL(0x006c2a84678e4b3bULL, 0x007a194aacd1868fULL, + 0x00ed0225af424761ULL, 0x00da0a6f293c64b8ULL, + 0x001062ac5c6a7a18ULL, 0x0030f5775a8aeef4ULL, + 0x0002acaad76b7af0ULL, 0x00410b8fd63a579fULL)}, + {FIELD_LITERAL(0x001ec59db3d9590eULL, 0x001e9e3f1c3f182dULL, + 0x0045a9c3ec2cab14ULL, 0x0008198572aeb673ULL, + 0x00773b74068bd167ULL, 0x0012535eaa395434ULL, + 0x0044dba9e3bbb74aULL, 0x002fba4d3c74bd0eULL)}, + {FIELD_LITERAL(0x0042bf08fe66922cULL, 0x003318b8fbb49e8cULL, + 0x00d75946004aa14cULL, 0x00f601586b42bf1cULL, + 0x00c74cf1d912fe66ULL, 0x00abcb36974b30adULL, + 0x007eb78720c9d2b8ULL, 0x009f54ab7bd4df85ULL)}, }}, {{ - {FIELD_LITERAL(0x00db9fc948f73826, 0x00fa8b3746ed8ee9, - 0x00132cb65aafbeb2, 0x00c36ff3fe7925b8, - 0x00837daed353d2fe, 0x00ec661be0667cf4, - 0x005beb8ed2e90204, 0x00d77dd69e564967)}, - {FIELD_LITERAL(0x0042e6268b861751, 0x0008dd0469500c16, - 0x00b51b57c338a3fd, 0x00cc4497d85cff6b, - 0x002f13d6b57c34a4, 0x0083652eaf301105, - 0x00cc344294cc93a8, 0x0060f4d02810e270)}, - {FIELD_LITERAL(0x00a8954363cd518b, 0x00ad171124bccb7b, - 0x0065f46a4adaae00, 0x001b1a5b2a96e500, - 0x0043fe24f8233285, 0x0066996d8ae1f2c3, - 0x00c530f3264169f9, 0x00c0f92d07cf6a57)}, + {FIELD_LITERAL(0x00db9fc948f73826ULL, 0x00fa8b3746ed8ee9ULL, + 0x00132cb65aafbeb2ULL, 0x00c36ff3fe7925b8ULL, + 0x00837daed353d2feULL, 0x00ec661be0667cf4ULL, + 0x005beb8ed2e90204ULL, 0x00d77dd69e564967ULL)}, + {FIELD_LITERAL(0x0042e6268b861751ULL, 0x0008dd0469500c16ULL, + 0x00b51b57c338a3fdULL, 0x00cc4497d85cff6bULL, + 0x002f13d6b57c34a4ULL, 0x0083652eaf301105ULL, + 0x00cc344294cc93a8ULL, 0x0060f4d02810e270ULL)}, + {FIELD_LITERAL(0x00a8954363cd518bULL, 0x00ad171124bccb7bULL, + 0x0065f46a4adaae00ULL, 0x001b1a5b2a96e500ULL, + 0x0043fe24f8233285ULL, 0x0066996d8ae1f2c3ULL, + 0x00c530f3264169f9ULL, 0x00c0f92d07cf6a57ULL)}, }}, {{ - {FIELD_LITERAL(0x0036a55c6815d943, 0x008c8d1def993db3, - 0x002e0e1e8ff7318f, 0x00d883a4b92db00a, - 0x002f5e781ae33906, 0x001a72adb235c06d, - 0x00f2e59e736e9caa, 0x001a4b58e3031914)}, - {FIELD_LITERAL(0x00d73bfae5e00844, 0x00bf459766fb5f52, - 0x0061b4f5a5313cde, 0x004392d4c3b95514, - 0x000d3551b1077523, 0x0000998840ee5d71, - 0x006de6e340448b7b, 0x00251aa504875d6e)}, - {FIELD_LITERAL(0x003bf343427ac342, 0x00adc0a78642b8c5, - 0x0003b893175a8314, 0x0061a34ade5703bc, - 0x00ea3ea8bb71d632, 0x00be0df9a1f198c2, - 0x0046dd8e7c1635fb, 0x00f1523fdd25d5e5)}, + {FIELD_LITERAL(0x0036a55c6815d943ULL, 0x008c8d1def993db3ULL, + 0x002e0e1e8ff7318fULL, 0x00d883a4b92db00aULL, + 0x002f5e781ae33906ULL, 0x001a72adb235c06dULL, + 0x00f2e59e736e9caaULL, 0x001a4b58e3031914ULL)}, + {FIELD_LITERAL(0x00d73bfae5e00844ULL, 0x00bf459766fb5f52ULL, + 0x0061b4f5a5313cdeULL, 0x004392d4c3b95514ULL, + 0x000d3551b1077523ULL, 0x0000998840ee5d71ULL, + 0x006de6e340448b7bULL, 0x00251aa504875d6eULL)}, + {FIELD_LITERAL(0x003bf343427ac342ULL, 0x00adc0a78642b8c5ULL, + 0x0003b893175a8314ULL, 0x0061a34ade5703bcULL, + 0x00ea3ea8bb71d632ULL, 0x00be0df9a1f198c2ULL, + 0x0046dd8e7c1635fbULL, 0x00f1523fdd25d5e5ULL)}, }}, {{ - {FIELD_LITERAL(0x00633f63fc9dd406, 0x00e713ff80e04a43, - 0x0060c6e970f2d621, 0x00a57cd7f0df1891, - 0x00f2406a550650bb, 0x00b064290efdc684, - 0x001eab0144d17916, 0x00cd15f863c293ab)}, - {FIELD_LITERAL(0x0029cec55273f70d, 0x007044ee275c6340, - 0x0040f637a93015e2, 0x00338bb78db5aae9, - 0x001491b2a6132147, 0x00a125d6cfe6bde3, - 0x005f7ac561ba8669, 0x001d5eaea3fbaacf)}, - {FIELD_LITERAL(0x00054e9635e3be31, 0x000e43f31e2872be, - 0x00d05b1c9e339841, 0x006fac50bd81fd98, - 0x00cdc7852eaebb09, 0x004ff519b061991b, - 0x009099e8107d4c85, 0x00273e24c36a4a61)}, + {FIELD_LITERAL(0x00633f63fc9dd406ULL, 0x00e713ff80e04a43ULL, + 0x0060c6e970f2d621ULL, 0x00a57cd7f0df1891ULL, + 0x00f2406a550650bbULL, 0x00b064290efdc684ULL, + 0x001eab0144d17916ULL, 0x00cd15f863c293abULL)}, + {FIELD_LITERAL(0x0029cec55273f70dULL, 0x007044ee275c6340ULL, + 0x0040f637a93015e2ULL, 0x00338bb78db5aae9ULL, + 0x001491b2a6132147ULL, 0x00a125d6cfe6bde3ULL, + 0x005f7ac561ba8669ULL, 0x001d5eaea3fbaacfULL)}, + {FIELD_LITERAL(0x00054e9635e3be31ULL, 0x000e43f31e2872beULL, + 0x00d05b1c9e339841ULL, 0x006fac50bd81fd98ULL, + 0x00cdc7852eaebb09ULL, 0x004ff519b061991bULL, + 0x009099e8107d4c85ULL, 0x00273e24c36a4a61ULL)}, }}, {{ - {FIELD_LITERAL(0x00070b4441ef2c46, 0x00efa5b02801a109, - 0x00bf0b8c3ee64adf, 0x008a67e0b3452e98, - 0x001916b1f2fa7a74, 0x00d781a78ff6cdc3, - 0x008682ce57e5c919, 0x00cc1109dd210da3)}, - {FIELD_LITERAL(0x00cae8aaff388663, 0x005e983a35dda1c7, - 0x007ab1030d8e37f4, 0x00e48940f5d032fe, - 0x006a36f9ef30b331, 0x009be6f03958c757, - 0x0086231ceba91400, 0x008bd0f7b823e7aa)}, - {FIELD_LITERAL(0x00cf881ebef5a45a, 0x004ebea78e7c6f2c, - 0x0090da9209cf26a0, 0x00de2b2e4c775b84, - 0x0071d6031c3c15ae, 0x00d9e927ef177d70, - 0x00894ee8c23896fd, 0x00e3b3b401e41aad)}, + {FIELD_LITERAL(0x00070b4441ef2c46ULL, 0x00efa5b02801a109ULL, + 0x00bf0b8c3ee64adfULL, 0x008a67e0b3452e98ULL, + 0x001916b1f2fa7a74ULL, 0x00d781a78ff6cdc3ULL, + 0x008682ce57e5c919ULL, 0x00cc1109dd210da3ULL)}, + {FIELD_LITERAL(0x00cae8aaff388663ULL, 0x005e983a35dda1c7ULL, + 0x007ab1030d8e37f4ULL, 0x00e48940f5d032feULL, + 0x006a36f9ef30b331ULL, 0x009be6f03958c757ULL, + 0x0086231ceba91400ULL, 0x008bd0f7b823e7aaULL)}, + {FIELD_LITERAL(0x00cf881ebef5a45aULL, 0x004ebea78e7c6f2cULL, + 0x0090da9209cf26a0ULL, 0x00de2b2e4c775b84ULL, + 0x0071d6031c3c15aeULL, 0x00d9e927ef177d70ULL, + 0x00894ee8c23896fdULL, 0x00e3b3b401e41aadULL)}, }}, {{ - {FIELD_LITERAL(0x00204fef26864170, 0x00819269c5dee0f8, - 0x00bfb4713ec97966, 0x0026339a6f34df78, - 0x001f26e64c761dc2, 0x00effe3af313cb60, - 0x00e17b70138f601b, 0x00f16e1ccd9ede5e)}, - {FIELD_LITERAL(0x005d9a8353fdb2db, 0x0055cc2048c698f0, - 0x00f6c4ac89657218, 0x00525034d73faeb2, - 0x00435776fbda3c7d, 0x0070ea5312323cbc, - 0x007a105d44d069fb, 0x006dbc8d6dc786aa)}, - {FIELD_LITERAL(0x0017cff19cd394ec, 0x00fef7b810922587, - 0x00e6483970dff548, 0x00ddf36ad6874264, - 0x00e61778523fcce2, 0x0093a66c0c93b24a, - 0x00fd367114db7f86, 0x007652d7ddce26dd)}, + {FIELD_LITERAL(0x00204fef26864170ULL, 0x00819269c5dee0f8ULL, + 0x00bfb4713ec97966ULL, 0x0026339a6f34df78ULL, + 0x001f26e64c761dc2ULL, 0x00effe3af313cb60ULL, + 0x00e17b70138f601bULL, 0x00f16e1ccd9ede5eULL)}, + {FIELD_LITERAL(0x005d9a8353fdb2dbULL, 0x0055cc2048c698f0ULL, + 0x00f6c4ac89657218ULL, 0x00525034d73faeb2ULL, + 0x00435776fbda3c7dULL, 0x0070ea5312323cbcULL, + 0x007a105d44d069fbULL, 0x006dbc8d6dc786aaULL)}, + {FIELD_LITERAL(0x0017cff19cd394ecULL, 0x00fef7b810922587ULL, + 0x00e6483970dff548ULL, 0x00ddf36ad6874264ULL, + 0x00e61778523fcce2ULL, 0x0093a66c0c93b24aULL, + 0x00fd367114db7f86ULL, 0x007652d7ddce26ddULL)}, }}, {{ - {FIELD_LITERAL(0x00d92ced7ba12843, 0x00aea9c7771e86e7, - 0x0046639693354f7b, 0x00a628dbb6a80c47, - 0x003a0b0507372953, 0x00421113ab45c0d9, - 0x00e545f08362ab7a, 0x0028ce087b4d6d96)}, - {FIELD_LITERAL(0x00a67ee7cf9f99eb, 0x005713b275f2ff68, - 0x00f1d536a841513d, 0x00823b59b024712e, - 0x009c46b9d0d38cec, 0x00cdb1595aa2d7d4, - 0x008375b3423d9af8, 0x000ab0b516d978f7)}, - {FIELD_LITERAL(0x00428dcb3c510b0f, 0x00585607ea24bb4e, - 0x003736bf1603687a, 0x00c47e568c4fe3c7, - 0x003cd00282848605, 0x0043a487c3b91939, - 0x004ffc04e1095a06, 0x00a4c989a3d4b918)}, + {FIELD_LITERAL(0x00d92ced7ba12843ULL, 0x00aea9c7771e86e7ULL, + 0x0046639693354f7bULL, 0x00a628dbb6a80c47ULL, + 0x003a0b0507372953ULL, 0x00421113ab45c0d9ULL, + 0x00e545f08362ab7aULL, 0x0028ce087b4d6d96ULL)}, + {FIELD_LITERAL(0x00a67ee7cf9f99ebULL, 0x005713b275f2ff68ULL, + 0x00f1d536a841513dULL, 0x00823b59b024712eULL, + 0x009c46b9d0d38cecULL, 0x00cdb1595aa2d7d4ULL, + 0x008375b3423d9af8ULL, 0x000ab0b516d978f7ULL)}, + {FIELD_LITERAL(0x00428dcb3c510b0fULL, 0x00585607ea24bb4eULL, + 0x003736bf1603687aULL, 0x00c47e568c4fe3c7ULL, + 0x003cd00282848605ULL, 0x0043a487c3b91939ULL, + 0x004ffc04e1095a06ULL, 0x00a4c989a3d4b918ULL)}, }}, {{ - {FIELD_LITERAL(0x00a8778d0e429f7a, 0x004c02b059105a68, - 0x0016653b609da3ff, 0x00d5107bd1a12d27, - 0x00b4708f9a771cab, 0x00bb63b662033f69, - 0x0072f322240e7215, 0x0019445b59c69222)}, - {FIELD_LITERAL(0x00cf4f6069a658e6, 0x0053ca52859436a6, - 0x0064b994d7e3e117, 0x00cb469b9a07f534, - 0x00cfb68f399e9d47, 0x00f0dcb8dac1c6e7, - 0x00f2ab67f538b3a5, 0x0055544f178ab975)}, - {FIELD_LITERAL(0x0099b7a2685d538c, 0x00e2f1897b7c0018, - 0x003adac8ce48dae3, 0x00089276d5c50c0c, - 0x00172fca07ad6717, 0x00cb1a72f54069e5, - 0x004ee42f133545b3, 0x00785f8651362f16)}, + {FIELD_LITERAL(0x00a8778d0e429f7aULL, 0x004c02b059105a68ULL, + 0x0016653b609da3ffULL, 0x00d5107bd1a12d27ULL, + 0x00b4708f9a771cabULL, 0x00bb63b662033f69ULL, + 0x0072f322240e7215ULL, 0x0019445b59c69222ULL)}, + {FIELD_LITERAL(0x00cf4f6069a658e6ULL, 0x0053ca52859436a6ULL, + 0x0064b994d7e3e117ULL, 0x00cb469b9a07f534ULL, + 0x00cfb68f399e9d47ULL, 0x00f0dcb8dac1c6e7ULL, + 0x00f2ab67f538b3a5ULL, 0x0055544f178ab975ULL)}, + {FIELD_LITERAL(0x0099b7a2685d538cULL, 0x00e2f1897b7c0018ULL, + 0x003adac8ce48dae3ULL, 0x00089276d5c50c0cULL, + 0x00172fca07ad6717ULL, 0x00cb1a72f54069e5ULL, + 0x004ee42f133545b3ULL, 0x00785f8651362f16ULL)}, }}, {{ - {FIELD_LITERAL(0x0049cbac38509e11, 0x0015234505d42cdf, - 0x00794fb0b5840f1c, 0x00496437344045a5, - 0x0031b6d944e4f9b0, 0x00b207318ac1f5d8, - 0x0000c840da7f5c5d, 0x00526f373a5c8814)}, - {FIELD_LITERAL(0x002c7b7742d1dfd9, 0x002cabeb18623c01, - 0x00055f5e3e044446, 0x006c20f3b4ef54ba, - 0x00c600141ec6b35f, 0x00354f437f1a32a3, - 0x00bac4624a3520f9, 0x00c483f734a90691)}, - {FIELD_LITERAL(0x0053a737d422918d, 0x00f7fca1d8758625, - 0x00c360336dadb04c, 0x00f38e3d9158a1b8, - 0x0069ce3b418e84c6, 0x005d1697eca16ead, - 0x00f8bd6a35ece13d, 0x007885dfc2b5afea)}, + {FIELD_LITERAL(0x0049cbac38509e11ULL, 0x0015234505d42cdfULL, + 0x00794fb0b5840f1cULL, 0x00496437344045a5ULL, + 0x0031b6d944e4f9b0ULL, 0x00b207318ac1f5d8ULL, + 0x0000c840da7f5c5dULL, 0x00526f373a5c8814ULL)}, + {FIELD_LITERAL(0x002c7b7742d1dfd9ULL, 0x002cabeb18623c01ULL, + 0x00055f5e3e044446ULL, 0x006c20f3b4ef54baULL, + 0x00c600141ec6b35fULL, 0x00354f437f1a32a3ULL, + 0x00bac4624a3520f9ULL, 0x00c483f734a90691ULL)}, + {FIELD_LITERAL(0x0053a737d422918dULL, 0x00f7fca1d8758625ULL, + 0x00c360336dadb04cULL, 0x00f38e3d9158a1b8ULL, + 0x0069ce3b418e84c6ULL, 0x005d1697eca16eadULL, + 0x00f8bd6a35ece13dULL, 0x007885dfc2b5afeaULL)}, }}, {{ - {FIELD_LITERAL(0x00c3617ae260776c, 0x00b20dc3e96922d7, - 0x00a1a7802246706a, 0x00ca6505a5240244, - 0x002246b62d919782, 0x001439102d7aa9b3, - 0x00e8af1139e6422c, 0x00c888d1b52f2b05)}, - {FIELD_LITERAL(0x005b67690ffd41d9, 0x005294f28df516f9, - 0x00a879272412fcb9, 0x00098b629a6d1c8d, - 0x00fabd3c8050865a, 0x00cd7e5b0a3879c5, - 0x00153238210f3423, 0x00357cac101e9f42)}, - {FIELD_LITERAL(0x008917b454444fb7, 0x00f59247c97e441b, - 0x00a6200a6815152d, 0x0009a4228601d254, - 0x001c0360559bd374, 0x007563362039cb36, - 0x00bd75b48d74e32b, 0x0017f515ac3499e8)}, + {FIELD_LITERAL(0x00c3617ae260776cULL, 0x00b20dc3e96922d7ULL, + 0x00a1a7802246706aULL, 0x00ca6505a5240244ULL, + 0x002246b62d919782ULL, 0x001439102d7aa9b3ULL, + 0x00e8af1139e6422cULL, 0x00c888d1b52f2b05ULL)}, + {FIELD_LITERAL(0x005b67690ffd41d9ULL, 0x005294f28df516f9ULL, + 0x00a879272412fcb9ULL, 0x00098b629a6d1c8dULL, + 0x00fabd3c8050865aULL, 0x00cd7e5b0a3879c5ULL, + 0x00153238210f3423ULL, 0x00357cac101e9f42ULL)}, + {FIELD_LITERAL(0x008917b454444fb7ULL, 0x00f59247c97e441bULL, + 0x00a6200a6815152dULL, 0x0009a4228601d254ULL, + 0x001c0360559bd374ULL, 0x007563362039cb36ULL, + 0x00bd75b48d74e32bULL, 0x0017f515ac3499e8ULL)}, }}, {{ - {FIELD_LITERAL(0x001532a7ffe41c5a, 0x00eb1edce358d6bf, - 0x00ddbacc7b678a7b, 0x008a7b70f3c841a3, - 0x00f1923bf27d3f4c, 0x000b2713ed8f7873, - 0x00aaf67e29047902, 0x0044994a70b3976d)}, - {FIELD_LITERAL(0x00d54e802082d42c, 0x00a55aa0dce7cc6c, - 0x006477b96073f146, 0x0082efe4ceb43594, - 0x00a922bcba026845, 0x0077f19d1ab75182, - 0x00c2bb2737846e59, 0x0004d7eec791dd33)}, - {FIELD_LITERAL(0x0044588d1a81d680, 0x00b0a9097208e4f8, - 0x00212605350dc57e, 0x0028717cd2871123, - 0x00fb083c100fd979, 0x0045a056ce063fdf, - 0x00a5d604b4dd6a41, 0x001dabc08ba4e236)}, + {FIELD_LITERAL(0x001532a7ffe41c5aULL, 0x00eb1edce358d6bfULL, + 0x00ddbacc7b678a7bULL, 0x008a7b70f3c841a3ULL, + 0x00f1923bf27d3f4cULL, 0x000b2713ed8f7873ULL, + 0x00aaf67e29047902ULL, 0x0044994a70b3976dULL)}, + {FIELD_LITERAL(0x00d54e802082d42cULL, 0x00a55aa0dce7cc6cULL, + 0x006477b96073f146ULL, 0x0082efe4ceb43594ULL, + 0x00a922bcba026845ULL, 0x0077f19d1ab75182ULL, + 0x00c2bb2737846e59ULL, 0x0004d7eec791dd33ULL)}, + {FIELD_LITERAL(0x0044588d1a81d680ULL, 0x00b0a9097208e4f8ULL, + 0x00212605350dc57eULL, 0x0028717cd2871123ULL, + 0x00fb083c100fd979ULL, 0x0045a056ce063fdfULL, + 0x00a5d604b4dd6a41ULL, 0x001dabc08ba4e236ULL)}, }}, {{ - {FIELD_LITERAL(0x00c4887198d7a7fa, 0x00244f98fb45784a, - 0x0045911e15a15d01, 0x001d323d374c0966, - 0x00967c3915196562, 0x0039373abd2f3c67, - 0x000d2c5614312423, 0x0041cf2215442ce3)}, - {FIELD_LITERAL(0x008ede889ada7f06, 0x001611e91de2e135, - 0x00fdb9a458a471b9, 0x00563484e03710d1, - 0x0031cc81925e3070, 0x0062c97b3af80005, - 0x00fa733eea28edeb, 0x00e82457e1ebbc88)}, - {FIELD_LITERAL(0x006a0df5fe9b6f59, 0x00a0d4ff46040d92, - 0x004a7cedb6f93250, 0x00d1df8855b8c357, - 0x00e73a46086fd058, 0x0048fb0add6dfe59, - 0x001e03a28f1b4e3d, 0x00a871c993308d76)}, + {FIELD_LITERAL(0x00c4887198d7a7faULL, 0x00244f98fb45784aULL, + 0x0045911e15a15d01ULL, 0x001d323d374c0966ULL, + 0x00967c3915196562ULL, 0x0039373abd2f3c67ULL, + 0x000d2c5614312423ULL, 0x0041cf2215442ce3ULL)}, + {FIELD_LITERAL(0x008ede889ada7f06ULL, 0x001611e91de2e135ULL, + 0x00fdb9a458a471b9ULL, 0x00563484e03710d1ULL, + 0x0031cc81925e3070ULL, 0x0062c97b3af80005ULL, + 0x00fa733eea28edebULL, 0x00e82457e1ebbc88ULL)}, + {FIELD_LITERAL(0x006a0df5fe9b6f59ULL, 0x00a0d4ff46040d92ULL, + 0x004a7cedb6f93250ULL, 0x00d1df8855b8c357ULL, + 0x00e73a46086fd058ULL, 0x0048fb0add6dfe59ULL, + 0x001e03a28f1b4e3dULL, 0x00a871c993308d76ULL)}, }}, {{ - {FIELD_LITERAL(0x0030dbb2d1766ec8, 0x00586c0ad138555e, - 0x00d1a34f9e91c77c, 0x0063408ad0e89014, - 0x00d61231b05f6f5b, 0x0009abf569f5fd8a, - 0x00aec67a110f1c43, 0x0031d1a790938dd7)}, - {FIELD_LITERAL(0x006cded841e2a862, 0x00198d60af0ab6fb, - 0x0018f09db809e750, 0x004e6ac676016263, - 0x00eafcd1620969cb, 0x002c9784ca34917d, - 0x0054f00079796de7, 0x00d9fab5c5972204)}, - {FIELD_LITERAL(0x004bd0fee2438a83, 0x00b571e62b0f83bd, - 0x0059287d7ce74800, 0x00fb3631b645c3f0, - 0x00a018e977f78494, 0x0091e27065c27b12, - 0x007696c1817165e0, 0x008c40be7c45ba3a)}, + {FIELD_LITERAL(0x0030dbb2d1766ec8ULL, 0x00586c0ad138555eULL, + 0x00d1a34f9e91c77cULL, 0x0063408ad0e89014ULL, + 0x00d61231b05f6f5bULL, 0x0009abf569f5fd8aULL, + 0x00aec67a110f1c43ULL, 0x0031d1a790938dd7ULL)}, + {FIELD_LITERAL(0x006cded841e2a862ULL, 0x00198d60af0ab6fbULL, + 0x0018f09db809e750ULL, 0x004e6ac676016263ULL, + 0x00eafcd1620969cbULL, 0x002c9784ca34917dULL, + 0x0054f00079796de7ULL, 0x00d9fab5c5972204ULL)}, + {FIELD_LITERAL(0x004bd0fee2438a83ULL, 0x00b571e62b0f83bdULL, + 0x0059287d7ce74800ULL, 0x00fb3631b645c3f0ULL, + 0x00a018e977f78494ULL, 0x0091e27065c27b12ULL, + 0x007696c1817165e0ULL, 0x008c40be7c45ba3aULL)}, }}, {{ - {FIELD_LITERAL(0x00a0f326327cb684, 0x001c7d0f672680ff, - 0x008c1c81ffb112d1, 0x00f8f801674eddc8, - 0x00e926d5d48c2a9d, 0x005bd6d954c6fe9a, - 0x004c6b24b4e33703, 0x00d05eb5c09105cc)}, - {FIELD_LITERAL(0x00d61731caacf2cf, 0x002df0c7609e01c5, - 0x00306172208b1e2b, 0x00b413fe4fb2b686, - 0x00826d360902a221, 0x003f8d056e67e7f7, - 0x0065025b0175e989, 0x00369add117865eb)}, - {FIELD_LITERAL(0x00aaf895aec2fa11, 0x000f892bc313eb52, - 0x005b1c794dad050b, 0x003f8ec4864cec14, - 0x00af81058d0b90e5, 0x00ebe43e183997bb, - 0x00a9d610f9f3e615, 0x007acd8eec2e88d3)}, + {FIELD_LITERAL(0x00a0f326327cb684ULL, 0x001c7d0f672680ffULL, + 0x008c1c81ffb112d1ULL, 0x00f8f801674eddc8ULL, + 0x00e926d5d48c2a9dULL, 0x005bd6d954c6fe9aULL, + 0x004c6b24b4e33703ULL, 0x00d05eb5c09105ccULL)}, + {FIELD_LITERAL(0x00d61731caacf2cfULL, 0x002df0c7609e01c5ULL, + 0x00306172208b1e2bULL, 0x00b413fe4fb2b686ULL, + 0x00826d360902a221ULL, 0x003f8d056e67e7f7ULL, + 0x0065025b0175e989ULL, 0x00369add117865ebULL)}, + {FIELD_LITERAL(0x00aaf895aec2fa11ULL, 0x000f892bc313eb52ULL, + 0x005b1c794dad050bULL, 0x003f8ec4864cec14ULL, + 0x00af81058d0b90e5ULL, 0x00ebe43e183997bbULL, + 0x00a9d610f9f3e615ULL, 0x007acd8eec2e88d3ULL)}, }}, {{ - {FIELD_LITERAL(0x0049b2fab13812a3, 0x00846db32cd60431, - 0x000177fa578c8d6c, 0x00047d0e2ad4bc51, - 0x00b158ba38d1e588, 0x006a45daad79e3f3, - 0x000997b93cab887b, 0x00c47ea42fa23dc3)}, - {FIELD_LITERAL(0x0012b6fef7aeb1ca, 0x009412768194b6a7, - 0x00ff0d351f23ab93, 0x007e8a14c1aff71b, - 0x006c1c0170c512bc, 0x0016243ea02ab2e5, - 0x007bb6865b303f3e, 0x0015ce6b29b159f4)}, - {FIELD_LITERAL(0x009961cd02e68108, 0x00e2035d3a1d0836, - 0x005d51f69b5e1a1d, 0x004bccb4ea36edcd, - 0x0069be6a7aeef268, 0x0063f4dd9de8d5a7, - 0x006283783092ca35, 0x0075a31af2c35409)}, + {FIELD_LITERAL(0x0049b2fab13812a3ULL, 0x00846db32cd60431ULL, + 0x000177fa578c8d6cULL, 0x00047d0e2ad4bc51ULL, + 0x00b158ba38d1e588ULL, 0x006a45daad79e3f3ULL, + 0x000997b93cab887bULL, 0x00c47ea42fa23dc3ULL)}, + {FIELD_LITERAL(0x0012b6fef7aeb1caULL, 0x009412768194b6a7ULL, + 0x00ff0d351f23ab93ULL, 0x007e8a14c1aff71bULL, + 0x006c1c0170c512bcULL, 0x0016243ea02ab2e5ULL, + 0x007bb6865b303f3eULL, 0x0015ce6b29b159f4ULL)}, + {FIELD_LITERAL(0x009961cd02e68108ULL, 0x00e2035d3a1d0836ULL, + 0x005d51f69b5e1a1dULL, 0x004bccb4ea36edcdULL, + 0x0069be6a7aeef268ULL, 0x0063f4dd9de8d5a7ULL, + 0x006283783092ca35ULL, 0x0075a31af2c35409ULL)}, }}, {{ - {FIELD_LITERAL(0x00c412365162e8cf, 0x00012283fb34388a, - 0x003e6543babf39e2, 0x00eead6b3a804978, - 0x0099c0314e8b326f, 0x00e98e0a8d477a4f, - 0x00d2eb96b127a687, 0x00ed8d7df87571bb)}, - {FIELD_LITERAL(0x00777463e308cacf, 0x00c8acb93950132d, - 0x00ebddbf4ca48b2c, 0x0026ad7ca0795a0a, - 0x00f99a3d9a715064, 0x000d60bcf9d4dfcc, - 0x005e65a73a437a06, 0x0019d536a8db56c8)}, - {FIELD_LITERAL(0x00192d7dd558d135, 0x0027cd6a8323ffa7, - 0x00239f1a412dc1e7, 0x0046b4b3be74fc5c, - 0x0020c47a2bef5bce, 0x00aa17e48f43862b, - 0x00f7e26c96342e5f, 0x0008011c530f39a9)}, + {FIELD_LITERAL(0x00c412365162e8cfULL, 0x00012283fb34388aULL, + 0x003e6543babf39e2ULL, 0x00eead6b3a804978ULL, + 0x0099c0314e8b326fULL, 0x00e98e0a8d477a4fULL, + 0x00d2eb96b127a687ULL, 0x00ed8d7df87571bbULL)}, + {FIELD_LITERAL(0x00777463e308cacfULL, 0x00c8acb93950132dULL, + 0x00ebddbf4ca48b2cULL, 0x0026ad7ca0795a0aULL, + 0x00f99a3d9a715064ULL, 0x000d60bcf9d4dfccULL, + 0x005e65a73a437a06ULL, 0x0019d536a8db56c8ULL)}, + {FIELD_LITERAL(0x00192d7dd558d135ULL, 0x0027cd6a8323ffa7ULL, + 0x00239f1a412dc1e7ULL, 0x0046b4b3be74fc5cULL, + 0x0020c47a2bef5bceULL, 0x00aa17e48f43862bULL, + 0x00f7e26c96342e5fULL, 0x0008011c530f39a9ULL)}, }}, {{ - {FIELD_LITERAL(0x00aad4ac569bf0f1, 0x00a67adc90b27740, - 0x0048551369a5751a, 0x0031252584a3306a, - 0x0084e15df770e6fc, 0x00d7bba1c74b5805, - 0x00a80ef223af1012, 0x0089c85ceb843a34)}, - {FIELD_LITERAL(0x00c4545be4a54004, 0x0099e11f60357e6c, - 0x001f3936d19515a6, 0x007793df84341a6e, - 0x0051061886717ffa, 0x00e9b0a660b28f85, - 0x0044ea685892de0d, 0x000257d2a1fda9d9)}, - {FIELD_LITERAL(0x007e8b01b24ac8a8, 0x006cf3b0b5ca1337, - 0x00f1607d3e36a570, 0x0039b7fab82991a1, - 0x00231777065840c5, 0x00998e5afdd346f9, - 0x00b7dc3e64acc85f, 0x00baacc748013ad6)}, + {FIELD_LITERAL(0x00aad4ac569bf0f1ULL, 0x00a67adc90b27740ULL, + 0x0048551369a5751aULL, 0x0031252584a3306aULL, + 0x0084e15df770e6fcULL, 0x00d7bba1c74b5805ULL, + 0x00a80ef223af1012ULL, 0x0089c85ceb843a34ULL)}, + {FIELD_LITERAL(0x00c4545be4a54004ULL, 0x0099e11f60357e6cULL, + 0x001f3936d19515a6ULL, 0x007793df84341a6eULL, + 0x0051061886717ffaULL, 0x00e9b0a660b28f85ULL, + 0x0044ea685892de0dULL, 0x000257d2a1fda9d9ULL)}, + {FIELD_LITERAL(0x007e8b01b24ac8a8ULL, 0x006cf3b0b5ca1337ULL, + 0x00f1607d3e36a570ULL, 0x0039b7fab82991a1ULL, + 0x00231777065840c5ULL, 0x00998e5afdd346f9ULL, + 0x00b7dc3e64acc85fULL, 0x00baacc748013ad6ULL)}, }}, {{ - {FIELD_LITERAL(0x008ea6a4177580bf, 0x005fa1953e3f0378, - 0x005fe409ac74d614, 0x00452327f477e047, - 0x00a4018507fb6073, 0x007b6e71951caac8, - 0x0012b42ab8a6ce91, 0x0080eca677294ab7)}, - {FIELD_LITERAL(0x00a53edc023ba69b, 0x00c6afa83ddde2e8, - 0x00c3f638b307b14e, 0x004a357a64414062, - 0x00e4d94d8b582dc9, 0x001739caf71695b7, - 0x0012431b2ae28de1, 0x003b6bc98682907c)}, - {FIELD_LITERAL(0x008a9a93be1f99d6, 0x0079fa627cc699c8, - 0x00b0cfb134ba84c8, 0x001c4b778249419a, - 0x00df4ab3d9c44f40, 0x009f596e6c1a9e3c, - 0x001979c0df237316, 0x00501e953a919b87)}, + {FIELD_LITERAL(0x008ea6a4177580bfULL, 0x005fa1953e3f0378ULL, + 0x005fe409ac74d614ULL, 0x00452327f477e047ULL, + 0x00a4018507fb6073ULL, 0x007b6e71951caac8ULL, + 0x0012b42ab8a6ce91ULL, 0x0080eca677294ab7ULL)}, + {FIELD_LITERAL(0x00a53edc023ba69bULL, 0x00c6afa83ddde2e8ULL, + 0x00c3f638b307b14eULL, 0x004a357a64414062ULL, + 0x00e4d94d8b582dc9ULL, 0x001739caf71695b7ULL, + 0x0012431b2ae28de1ULL, 0x003b6bc98682907cULL)}, + {FIELD_LITERAL(0x008a9a93be1f99d6ULL, 0x0079fa627cc699c8ULL, + 0x00b0cfb134ba84c8ULL, 0x001c4b778249419aULL, + 0x00df4ab3d9c44f40ULL, 0x009f596e6c1a9e3cULL, + 0x001979c0df237316ULL, 0x00501e953a919b87ULL)}, }} }; const niels_t *ossl_curve448_wnaf_base = curve448_wnaf_base_table; diff --git a/libs/openssl-3/crypto/ec/curve448/ed448.h b/libs/openssl-3/crypto/ec/curve448/ed448.h index 00b2bae58..f4f01892d 100644 --- a/libs/openssl-3/crypto/ec/curve448/ed448.h +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/crypto/ec/curve448/f_generic.c b/libs/openssl-3/crypto/ec/curve448/f_generic.c index d9af0ca86..9a4675a8b 100644 --- a/libs/openssl-3/crypto/ec/curve448/f_generic.c +++ b/libs/openssl-3/crypto/ec/curve448/f_generic.c @@ -12,9 +12,9 @@ #include "field.h" static const gf MODULUS = { - FIELD_LITERAL(0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff, - 0xffffffffffffff, 0xfffffffffffffe, 0xffffffffffffff, - 0xffffffffffffff, 0xffffffffffffff) + FIELD_LITERAL(0xffffffffffffffULL, 0xffffffffffffffULL, 0xffffffffffffffULL, + 0xffffffffffffffULL, 0xfffffffffffffeULL, 0xffffffffffffffULL, + 0xffffffffffffffULL, 0xffffffffffffffULL) }; /* Serialize to wire format. */ diff --git a/libs/openssl-3/crypto/ec/curve448/scalar.c b/libs/openssl-3/crypto/ec/curve448/scalar.c index 98353a4aa..99c0d83db 100644 --- a/libs/openssl-3/crypto/ec/curve448/scalar.c +++ b/libs/openssl-3/crypto/ec/curve448/scalar.c @@ -18,20 +18,20 @@ static const c448_word_t MONTGOMERY_FACTOR = (c448_word_t) 0x3bd440fae918bc5ULL; static const curve448_scalar_t sc_p = { { { - SC_LIMB(0x2378c292ab5844f3), SC_LIMB(0x216cc2728dc58f55), - SC_LIMB(0xc44edb49aed63690), SC_LIMB(0xffffffff7cca23e9), - SC_LIMB(0xffffffffffffffff), SC_LIMB(0xffffffffffffffff), - SC_LIMB(0x3fffffffffffffff) + SC_LIMB(0x2378c292ab5844f3ULL), SC_LIMB(0x216cc2728dc58f55ULL), + SC_LIMB(0xc44edb49aed63690ULL), SC_LIMB(0xffffffff7cca23e9ULL), + SC_LIMB(0xffffffffffffffffULL), SC_LIMB(0xffffffffffffffffULL), + SC_LIMB(0x3fffffffffffffffULL) } } }, sc_r2 = { { { - SC_LIMB(0xe3539257049b9b60), SC_LIMB(0x7af32c4bc1b195d9), - SC_LIMB(0x0d66de2388ea1859), SC_LIMB(0xae17cf725ee4d838), - SC_LIMB(0x1a9cc14ba3c47c44), SC_LIMB(0x2052bcb7e4d070af), - SC_LIMB(0x3402a939f823b729) + SC_LIMB(0xe3539257049b9b60ULL), SC_LIMB(0x7af32c4bc1b195d9ULL), + SC_LIMB(0x0d66de2388ea1859ULL), SC_LIMB(0xae17cf725ee4d838ULL), + SC_LIMB(0x1a9cc14ba3c47c44ULL), SC_LIMB(0x2052bcb7e4d070afULL), + SC_LIMB(0x3402a939f823b729ULL) } } }; diff --git a/libs/openssl-3/crypto/ec/curve448/word.h b/libs/openssl-3/crypto/ec/curve448/word.h index 1d157b744..f8292eef8 100644 --- a/libs/openssl-3/crypto/ec/curve448/word.h +++ b/libs/openssl-3/crypto/ec/curve448/word.h @@ -48,7 +48,7 @@ typedef int64_t dsword_t; # if C448_WORD_BITS == 64 # define SC_LIMB(x) (x) # elif C448_WORD_BITS == 32 -# define SC_LIMB(x) ((uint32_t)(x##ULL)),((x##ULL) >> 32) +# define SC_LIMB(x) ((uint32_t)(x)),((x) >> 32) # else # error "For now we only support 32- and 64-bit architectures." # endif diff --git a/libs/openssl-3/crypto/engine/eng_pkey.c b/libs/openssl-3/crypto/engine/eng_pkey.c index f84fcde46..d18d837e6 100644 --- a/libs/openssl-3/crypto/engine/eng_pkey.c +++ b/libs/openssl-3/crypto/engine/eng_pkey.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. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -79,48 +79,6 @@ EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, ERR_raise(ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PRIVATE_KEY); return NULL; } - /* We enforce check for legacy key */ - switch (EVP_PKEY_get_id(pkey)) { - case EVP_PKEY_RSA: - { - RSA *rsa = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_set1_RSA(pkey, rsa); - RSA_free(rsa); - } - break; -# ifndef OPENSSL_NO_EC - case EVP_PKEY_SM2: - case EVP_PKEY_EC: - { - EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pkey); - EVP_PKEY_set1_EC_KEY(pkey, ec); - EC_KEY_free(ec); - } - break; -# endif -# ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - { - DSA *dsa = EVP_PKEY_get1_DSA(pkey); - EVP_PKEY_set1_DSA(pkey, dsa); - DSA_free(dsa); - } - break; -#endif -# ifndef OPENSSL_NO_DH - case EVP_PKEY_DH: - { - DH *dh = EVP_PKEY_get1_DH(pkey); - EVP_PKEY_set1_DH(pkey, dh); - DH_free(dh); - } - break; -#endif - default: - /*Do nothing */ - break; - } - return pkey; } diff --git a/libs/openssl-3/crypto/err/err_mark.c b/libs/openssl-3/crypto/err/err_mark.c index 82dc4764c..cb01a1f4f 100644 --- a/libs/openssl-3/crypto/err/err_mark.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/err/openssl.ec b/libs/openssl-3/crypto/err/openssl.ec index f1917136d..f3802a05b 100644 --- a/libs/openssl-3/crypto/err/openssl.ec +++ b/libs/openssl-3/crypto/err/openssl.ec @@ -76,4 +76,6 @@ R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 R SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +R SSL_R_TLSV1_ALERT_UNKNOWN_PSK_IDENTITY 1115 R SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED 1116 +R SSL_R_TLSV1_ALERT_NO_APPLICATION_PROTOCOL 1120 diff --git a/libs/openssl-3/crypto/err/openssl.txt b/libs/openssl-3/crypto/err/openssl.txt index a30d25e5c..6882eebcd 100644 --- a/libs/openssl-3/crypto/err/openssl.txt +++ b/libs/openssl-3/crypto/err/openssl.txt @@ -1,4 +1,4 @@ -# 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 @@ -32,6 +32,7 @@ ASN1_R_EXPLICIT_LENGTH_MISMATCH:119:explicit length mismatch ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED:120:explicit tag not constructed ASN1_R_FIELD_MISSING:121:field missing ASN1_R_FIRST_NUM_TOO_LARGE:122:first num too large +ASN1_R_GENERALIZEDTIME_IS_TOO_SHORT:232:generalizedtime is too short ASN1_R_HEADER_TOO_LONG:123:header too long ASN1_R_ILLEGAL_BITSTRING_FORMAT:175:illegal bitstring format ASN1_R_ILLEGAL_BOOLEAN:176:illegal boolean @@ -119,6 +120,7 @@ ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE:164:unsupported any defined by type ASN1_R_UNSUPPORTED_CIPHER:228:unsupported cipher ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE:167:unsupported public key type ASN1_R_UNSUPPORTED_TYPE:196:unsupported type +ASN1_R_UTCTIME_IS_TOO_SHORT:233:utctime is too short ASN1_R_WRONG_INTEGER_TYPE:225:wrong integer type ASN1_R_WRONG_PUBLIC_KEY_TYPE:200:wrong public key type ASN1_R_WRONG_TAG:168:wrong tag @@ -227,6 +229,7 @@ CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature +CMP_R_EXPECTED_POLLREQ:104:expected pollreq CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random @@ -272,14 +275,18 @@ CMP_R_TOTAL_TIMEOUT:184:total timeout CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched CMP_R_TRANSFER_ERROR:159:transfer error CMP_R_UNCLEAN_CTX:191:unclean ctx +CMP_R_UNEXPECTED_CERTPROFILE:196:unexpected certprofile CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus +CMP_R_UNEXPECTED_POLLREQ:105:unexpected pollreq CMP_R_UNEXPECTED_PVNO:153:unexpected pvno +CMP_R_UNEXPECTED_SENDER:106:unexpected sender CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type CMP_R_UNKNOWN_PKISTATUS:186:unknown pkistatus CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type +CMP_R_UNSUPPORTED_PKIBODY:101:unsupported pkibody CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC:154:\ unsupported protection alg dhbasedmac CMP_R_VALUE_TOO_LARGE:175:value too large @@ -830,6 +837,7 @@ HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error +HTTP_R_RESPONSE_TOO_MANY_HDRLINES:130:response too many hdrlines HTTP_R_RETRY_TIMEOUT:129:retry timeout HTTP_R_SERVER_CANCELED_CONNECTION:127:server canceled connection HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported @@ -1396,6 +1404,8 @@ SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch SSL_R_FAILED_TO_GET_PARAMETER:316:failed to get parameter SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async +SSL_R_FEATURE_NEGOTIATION_NOT_COMPLETE:417:feature negotiation not complete +SSL_R_FEATURE_NOT_RENEGOTIABLE:413:feature not renegotiable SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs SSL_R_HTTPS_PROXY_REQUEST:155:https proxy request @@ -1500,6 +1510,7 @@ SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE:199:peer did not return a certificate SSL_R_PEM_NAME_BAD_PREFIX:391:pem name bad prefix SSL_R_PEM_NAME_TOO_SHORT:392:pem name too short SSL_R_PIPELINE_FAILURE:406:pipeline failure +SSL_R_POLL_REQUEST_NOT_SUPPORTED:418:poll request not supported SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR:278:post handshake auth encoding err SSL_R_PRIVATE_KEY_MISMATCH:288:private key mismatch SSL_R_PROTOCOL_IS_SHUTDOWN:207:protocol is shutdown @@ -1585,10 +1596,13 @@ SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION:1060:tlsv1 alert export restriction SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK:1086:tlsv1 alert inappropriate fallback SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY:1071:tlsv1 alert insufficient security SSL_R_TLSV1_ALERT_INTERNAL_ERROR:1080:tlsv1 alert internal error +SSL_R_TLSV1_ALERT_NO_APPLICATION_PROTOCOL:1120:\ + tlsv1 alert no application protocol SSL_R_TLSV1_ALERT_NO_RENEGOTIATION:1100:tlsv1 alert no renegotiation SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:1070:tlsv1 alert protocol version SSL_R_TLSV1_ALERT_RECORD_OVERFLOW:1022:tlsv1 alert record overflow SSL_R_TLSV1_ALERT_UNKNOWN_CA:1048:tlsv1 alert unknown ca +SSL_R_TLSV1_ALERT_UNKNOWN_PSK_IDENTITY:1115:tlsv1 alert unknown psk identity SSL_R_TLSV1_ALERT_USER_CANCELLED:1090:tlsv1 alert user cancelled SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE:1114:tlsv1 bad certificate hash value SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE:1113:\ @@ -1629,10 +1643,14 @@ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED:338:\ unsafe legacy renegotiation disabled SSL_R_UNSOLICITED_EXTENSION:217:unsolicited extension SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM:257:unsupported compression algorithm +SSL_R_UNSUPPORTED_CONFIG_VALUE:414:unsupported config value +SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS:415:unsupported config value class +SSL_R_UNSUPPORTED_CONFIG_VALUE_OP:416:unsupported config value op SSL_R_UNSUPPORTED_ELLIPTIC_CURVE:315:unsupported elliptic curve SSL_R_UNSUPPORTED_PROTOCOL:258:unsupported protocol SSL_R_UNSUPPORTED_SSL_VERSION:259:unsupported ssl version SSL_R_UNSUPPORTED_STATUS_TYPE:329:unsupported status type +SSL_R_UNSUPPORTED_WRITE_FLAG:412:unsupported write flag SSL_R_USE_SRTP_NOT_NEGOTIATED:369:use srtp not negotiated SSL_R_VERSION_TOO_HIGH:166:version too high SSL_R_VERSION_TOO_LOW:396:version too low diff --git a/libs/openssl-3/crypto/ess/ess_lib.c b/libs/openssl-3/crypto/ess/ess_lib.c index 0612e68ee..ff174470d 100644 --- a/libs/openssl-3/crypto/ess/ess_lib.c +++ b/libs/openssl-3/crypto/ess/ess_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 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 @@ -346,7 +346,7 @@ int OSSL_ESS_check_signing_certs(const ESS_SIGNING_CERT *ss, int i, ret; if (require_signing_cert && ss == NULL && ssv2 == NULL) { - ERR_raise(ERR_LIB_CMS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE); + ERR_raise(ERR_LIB_ESS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE); return -1; } if (n_v1 == 0 || n_v2 == 0) { diff --git a/libs/openssl-3/crypto/evp/bio_enc.c b/libs/openssl-3/crypto/evp/bio_enc.c index ece3f6d57..ffe4b5bb0 100644 --- a/libs/openssl-3/crypto/evp/bio_enc.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/evp/digest.c b/libs/openssl-3/crypto/evp/digest.c index 42331703d..ab670a8f4 100644 --- a/libs/openssl-3/crypto/evp/digest.c +++ b/libs/openssl-3/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 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size) 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 diff --git a/libs/openssl-3/crypto/evp/evp_enc.c b/libs/openssl-3/crypto/evp/evp_enc.c index e9faf3105..c289b2f7b 100644 --- a/libs/openssl-3/crypto/evp/evp_enc.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/evp/evp_fetch.c b/libs/openssl-3/crypto/evp/evp_fetch.c index e87c33fc6..2067c4062 100644 --- a/libs/openssl-3/crypto/evp/evp_fetch.c +++ b/libs/openssl-3/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__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); diff --git a/libs/openssl-3/crypto/evp/evp_key.c b/libs/openssl-3/crypto/evp/evp_key.c index 607d45ee2..7ef94e44e 100644 --- a/libs/openssl-3/crypto/evp/evp_key.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/evp/evp_lib.c b/libs/openssl-3/crypto/evp/evp_lib.c index f29d592e0..be95668c7 100644 --- a/libs/openssl-3/crypto/evp/evp_lib.c +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/crypto/evp/evp_local.h b/libs/openssl-3/crypto/evp/evp_local.h index 9e4059d70..8c1ff35cf 100644 --- a/libs/openssl-3/crypto/evp/evp_local.h +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/evp/keymgmt_meth.c b/libs/openssl-3/crypto/evp/keymgmt_meth.c index 1d7031f33..e3bec60ab 100644 --- a/libs/openssl-3/crypto/evp/keymgmt_meth.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/evp/legacy_sha.c b/libs/openssl-3/crypto/evp/legacy_sha.c index ca9a32649..38423ff54 100644 --- a/libs/openssl-3/crypto/evp/legacy_sha.c +++ b/libs/openssl-3/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) \ diff --git a/libs/openssl-3/crypto/evp/pmeth_lib.c b/libs/openssl-3/crypto/evp/pmeth_lib.c index 2caff2cd6..0a561323f 100644 --- a/libs/openssl-3/crypto/evp/pmeth_lib.c +++ b/libs/openssl-3/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) { diff --git a/libs/openssl-3/crypto/ffc/ffc_dh.c b/libs/openssl-3/crypto/ffc/ffc_dh.c index 3188761fb..df07e173b 100644 --- a/libs/openssl-3/crypto/ffc/ffc_dh.c +++ b/libs/openssl-3/crypto/ffc/ffc_dh.c @@ -10,7 +10,6 @@ #include "internal/ffc.h" #include "internal/nelem.h" #include "crypto/bn_dh.h" -#include "../bn/bn_local.h" // WINSCP #ifndef OPENSSL_NO_DH diff --git a/libs/openssl-3/crypto/hpke/hpke.c b/libs/openssl-3/crypto/hpke/hpke.c index 5e976d615..a53488d9e 100644 --- a/libs/openssl-3/crypto/hpke/hpke.c +++ b/libs/openssl-3/crypto/hpke/hpke.c @@ -1,7 +1,7 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html diff --git a/libs/openssl-3/crypto/http/http_client.c b/libs/openssl-3/crypto/http/http_client.c index acc32769a..9309954ef 100644 --- a/libs/openssl-3/crypto/http/http_client.c +++ b/libs/openssl-3/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) { diff --git a/libs/openssl-3/crypto/http/http_err.c b/libs/openssl-3/crypto/http/http_err.c index 332ad926d..22c2b40e6 100644 --- a/libs/openssl-3/crypto/http/http_err.c +++ b/libs/openssl-3/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 #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 diff --git a/libs/openssl-3/crypto/initthread.c b/libs/openssl-3/crypto/initthread.c index ae234cd20..e4d830d7f 100644 --- a/libs/openssl-3/crypto/initthread.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/lhash/lh_stats.c b/libs/openssl-3/crypto/lhash/lh_stats.c index f128c0ba4..ea0a3252a 100644 --- a/libs/openssl-3/crypto/lhash/lh_stats.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/lhash/lhash.c b/libs/openssl-3/crypto/lhash/lhash.c index 0a475b71d..e0234ccbf 100644 --- a/libs/openssl-3/crypto/lhash/lhash.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/lhash/lhash_local.h b/libs/openssl-3/crypto/lhash/lhash_local.h index 088ac94d2..8da63b9ad 100644 --- a/libs/openssl-3/crypto/lhash/lhash_local.h +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/md5/md5_local.h b/libs/openssl-3/crypto/md5/md5_local.h index 894567c3f..fab8bb9da 100644 --- a/libs/openssl-3/crypto/md5/md5_local.h +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/modes/gcm128.c b/libs/openssl-3/crypto/modes/gcm128.c index 77ff5dd06..f8901ed07 100644 --- a/libs/openssl-3/crypto/modes/gcm128.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/objects/obj_dat.h b/libs/openssl-3/crypto/objects/obj_dat.h index 5292db3f0..eaf098159 100644 --- a/libs/openssl-3/crypto/objects/obj_dat.h +++ b/libs/openssl-3/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 */ diff --git a/libs/openssl-3/crypto/objects/obj_xref.h b/libs/openssl-3/crypto/objects/obj_xref.h index 913606f17..01339d9da 100644 --- a/libs/openssl-3/crypto/objects/obj_xref.h +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/objects/objects.txt b/libs/openssl-3/crypto/objects/objects.txt index 305b89c01..86c396037 100644 --- a/libs/openssl-3/crypto/objects/objects.txt +++ b/libs/openssl-3/crypto/objects/objects.txt @@ -284,6 +284,7 @@ id-smime-ct 47 : id-ct-geofeedCSVwithCRLF id-smime-ct 48 : id-ct-signedChecklist id-smime-ct 49 : id-ct-ASPA id-smime-ct 50 : id-ct-signedTAL +id-smime-ct 51 : id-ct-rpkiSignedPrefixList # S/MIME Attributes id-smime-aa 1 : id-smime-aa-receiptRequest diff --git a/libs/openssl-3/crypto/param_build.c b/libs/openssl-3/crypto/param_build.c index 799094da9..329404515 100644 --- a/libs/openssl-3/crypto/param_build.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/param_build_set.c b/libs/openssl-3/crypto/param_build_set.c index 1a9dbb64f..f205d1019 100644 --- a/libs/openssl-3/crypto/param_build_set.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/params_idx.c b/libs/openssl-3/crypto/params_idx.c index 70c832923..73ce11cba 100644 --- a/libs/openssl-3/crypto/params_idx.c +++ b/libs/openssl-3/crypto/params_idx.c @@ -109,7 +109,7 @@ int ossl_param_find_pidx(const char *s) break; case 's': if (strcmp("ize", s + 6) == 0) - return PIDX_CIPHER_PARAM_BLOCK_SIZE; + return PIDX_DIGEST_PARAM_BLOCK_SIZE; } } } @@ -245,7 +245,7 @@ int ossl_param_find_pidx(const char *s) } break; case '\0': - return PIDX_KDF_PARAM_DATA; + return PIDX_OBJECT_PARAM_DATA; } } } @@ -550,7 +550,7 @@ int ossl_param_find_pidx(const char *s) break; case 'm': if (strcmp("plicit-rejection", s + 2) == 0) - return PIDX_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION; + return PIDX_PKEY_PARAM_IMPLICIT_REJECTION; break; case 'n': switch(s[2]) { @@ -562,7 +562,7 @@ int ossl_param_find_pidx(const char *s) break; case 'f': if (strcmp("o", s + 3) == 0) - return PIDX_KDF_PARAM_INFO; + return PIDX_PASSPHRASE_PARAM_INFO; break; case 'p': if (strcmp("ut-type", s + 3) == 0) @@ -604,7 +604,7 @@ int ossl_param_find_pidx(const char *s) return PIDX_CIPHER_PARAM_IVLEN; break; case '\0': - return PIDX_CIPHER_PARAM_IV; + return PIDX_MAC_PARAM_IV; } } break; @@ -915,7 +915,7 @@ int ossl_param_find_pidx(const char *s) default: break; case '\0': - return PIDX_CIPHER_PARAM_MODE; + return PIDX_LIBSSL_RECORD_LAYER_PARAM_MODE; } break; case 'u': @@ -1165,7 +1165,7 @@ int ossl_param_find_pidx(const char *s) return PIDX_PKEY_PARAM_PUB_KEY; break; case '\0': - return PIDX_PKEY_PARAM_EC_P; + return PIDX_PKEY_PARAM_FFC_P; } break; case 'q': @@ -1477,6 +1477,10 @@ int ossl_param_find_pidx(const char *s) } } break; + case 'd': + if (strcmp("erive-from-pq", s + 5) == 0) + return PIDX_PKEY_PARAM_RSA_DERIVE_FROM_PQ; + break; case 'e': switch(s[5]) { default: @@ -1807,7 +1811,7 @@ int ossl_param_find_pidx(const char *s) break; case 'e': if (strcmp("d", s + 3) == 0) - return PIDX_PKEY_PARAM_EC_SEED; + return PIDX_PKEY_PARAM_FFC_SEED; break; case 'r': if (strcmp("ial", s + 3) == 0) @@ -1820,7 +1824,7 @@ int ossl_param_find_pidx(const char *s) break; case 'i': if (strcmp("ze", s + 2) == 0) - return PIDX_DIGEST_PARAM_SIZE; + return PIDX_MAC_PARAM_SIZE; break; case 'p': if (strcmp("eed", s + 2) == 0) @@ -2142,7 +2146,7 @@ int ossl_param_find_pidx(const char *s) break; case 't': if (strcmp("ls", s + 9) == 0) - return PIDX_CAPABILITY_TLS_GROUP_MIN_TLS; + return PIDX_CAPABILITY_TLS_SIGALG_MIN_TLS; } } } @@ -2493,7 +2497,7 @@ int ossl_param_find_pidx(const char *s) break; case 'y': if (strcmp("pe", s + 2) == 0) - return PIDX_OBJECT_PARAM_TYPE; + return PIDX_PKEY_PARAM_FFC_TYPE; } break; case 'u': @@ -2647,7 +2651,7 @@ int ossl_param_find_pidx(const char *s) return PIDX_DIGEST_PARAM_XOFLEN; break; case '\0': - return PIDX_DIGEST_PARAM_XOF; + return PIDX_MAC_PARAM_XOF; } } break; diff --git a/libs/openssl-3/crypto/pkcs12/p12_decr.c b/libs/openssl-3/crypto/pkcs12/p12_decr.c index b916db0ab..3fa9c9c8c 100644 --- a/libs/openssl-3/crypto/pkcs12/p12_decr.c +++ b/libs/openssl-3/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) { diff --git a/libs/openssl-3/crypto/pkcs7/pk7_attr.c b/libs/openssl-3/crypto/pkcs7/pk7_attr.c index aa27dfdda..a12d65bb8 100644 --- a/libs/openssl-3/crypto/pkcs7/pk7_attr.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/pkcs7/pk7_smime.c b/libs/openssl-3/crypto/pkcs7/pk7_smime.c index 1f951d77f..747c41771 100644 --- a/libs/openssl-3/crypto/pkcs7/pk7_smime.c +++ b/libs/openssl-3/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)); diff --git a/libs/openssl-3/crypto/poly1305/poly1305_ieee754.c b/libs/openssl-3/crypto/poly1305/poly1305_ieee754.c index fa0ab1ed1..57a08aa24 100644 --- a/libs/openssl-3/crypto/poly1305/poly1305_ieee754.c +++ b/libs/openssl-3/crypto/poly1305/poly1305_ieee754.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 @@ -69,7 +69,7 @@ typedef union { double d; u64 u; } elem64; #if defined(__x86_64__) || (defined(__PPC__) && defined(__LITTLE_ENDIAN__)) # define U8TOU32(p) (*(const u32 *)(p)) # define U32TO8(p,v) (*(u32 *)(p) = (v)) -#elif defined(__PPC__) +#elif defined(__PPC__) || defined(__POWERPC__) # define U8TOU32(p) ({u32 ret; asm ("lwbrx %0,0,%1":"=r"(ret):"b"(p)); ret; }) # define U32TO8(p,v) asm ("stwbrx %0,0,%1"::"r"(v),"b"(p):"memory") #elif defined(__s390x__) @@ -95,7 +95,7 @@ typedef struct { /* "round toward zero (truncate), mask all exceptions" */ #if defined(__x86_64__) static const u32 mxcsr = 0x7f80; -#elif defined(__PPC__) +#elif defined(__PPC__) || defined(__POWERPC__) static const u64 one = 1; #elif defined(__s390x__) static const u32 fpc = 1; @@ -134,7 +134,7 @@ int poly1305_init(void *ctx, const unsigned char key[16]) asm volatile ("stmxcsr %0":"=m"(mxcsr_orig)); asm volatile ("ldmxcsr %0"::"m"(mxcsr)); -#elif defined(__PPC__) +#elif defined(__PPC__) || defined(__POWERPC__) double fpscr_orig, fpscr = *(double *)&one; asm volatile ("mffs %0":"=f"(fpscr_orig)); @@ -207,7 +207,7 @@ int poly1305_init(void *ctx, const unsigned char key[16]) */ #if defined(__x86_64__) asm volatile ("ldmxcsr %0"::"m"(mxcsr_orig)); -#elif defined(__PPC__) +#elif defined(__PPC__) || defined(__POWERPC__) asm volatile ("mtfsf 255,%0"::"f"(fpscr_orig)); #elif defined(__s390x__) asm volatile ("lfpc %0"::"m"(fpc_orig)); @@ -256,7 +256,7 @@ void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, asm volatile ("stmxcsr %0":"=m"(mxcsr_orig)); asm volatile ("ldmxcsr %0"::"m"(mxcsr)); -#elif defined(__PPC__) +#elif defined(__PPC__) || defined(__POWERPC__) double fpscr_orig, fpscr = *(double *)&one; asm volatile ("mffs %0":"=f"(fpscr_orig)); @@ -416,7 +416,7 @@ void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, */ #if defined(__x86_64__) asm volatile ("ldmxcsr %0"::"m"(mxcsr_orig)); -#elif defined(__PPC__) +#elif defined(__PPC__) || defined(__POWERPC__) asm volatile ("mtfsf 255,%0"::"f"(fpscr_orig)); #elif defined(__s390x__) asm volatile ("lfpc %0"::"m"(fpc_orig)); diff --git a/libs/openssl-3/crypto/provider_conf.c b/libs/openssl-3/crypto/provider_conf.c index ba2d92425..6a8b88e2e 100644 --- a/libs/openssl-3/crypto/provider_conf.c +++ b/libs/openssl-3/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) { diff --git a/libs/openssl-3/crypto/rand/rand_pool.c b/libs/openssl-3/crypto/rand/rand_pool.c index 8262ffe30..8d77b77fd 100644 --- a/libs/openssl-3/crypto/rand/rand_pool.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/rand/rand_uniform.c b/libs/openssl-3/crypto/rand/rand_uniform.c index b9e263585..f0b199b95 100644 --- a/libs/openssl-3/crypto/rand/rand_uniform.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/rcu_internal.h b/libs/openssl-3/crypto/rcu_internal.h new file mode 100644 index 000000000..fb718580e --- /dev/null +++ b/libs/openssl-3/crypto/rcu_internal.h @@ -0,0 +1,22 @@ +/* + * 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 OPENSSL_RCU_INTERNAL_H +# define OPENSSL_RCU_INTERNAL_H +# pragma once + +struct rcu_qp; + +struct rcu_cb_item { + rcu_cb_fn fn; + void *data; + struct rcu_cb_item *next; +}; + +#endif diff --git a/libs/openssl-3/crypto/riscvcap.c b/libs/openssl-3/crypto/riscvcap.c index 1cbfb4a57..db75c21b2 100644 --- a/libs/openssl-3/crypto/riscvcap.c +++ b/libs/openssl-3/crypto/riscvcap.c @@ -17,9 +17,13 @@ #define OPENSSL_RISCVCAP_IMPL #include "crypto/riscv_arch.h" +extern size_t riscv_vlen_asm(void); + static void parse_env(const char *envstr); static void strtoupper(char *str); +static size_t vlen = 0; + uint32_t OPENSSL_rdtsc(void) { return 0; @@ -67,6 +71,11 @@ static void parse_env(const char *envstr) } } +size_t riscv_vlen(void) +{ + return vlen; +} + # if defined(__GNUC__) && __GNUC__>=2 __attribute__ ((constructor)) # endif @@ -81,6 +90,9 @@ void OPENSSL_cpuid_setup(void) if ((e = getenv("OPENSSL_riscvcap"))) { parse_env(e); - return; + } + + if (RISCV_HAS_V()) { + vlen = riscv_vlen_asm(); } } diff --git a/libs/openssl-3/crypto/rsa/rsa_backend.c b/libs/openssl-3/crypto/rsa/rsa_backend.c index 62d0a4c3b..36ee28337 100644 --- a/libs/openssl-3/crypto/rsa/rsa_backend.c +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/crypto/rsa/rsa_gen.c b/libs/openssl-3/crypto/rsa/rsa_gen.c index 0cdbb3fde..75347d800 100644 --- a/libs/openssl-3/crypto/rsa/rsa_gen.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/rsa/rsa_lib.c b/libs/openssl-3/crypto/rsa/rsa_lib.c index 1c3b33c28..5350a4e65 100644 --- a/libs/openssl-3/crypto/rsa/rsa_lib.c +++ b/libs/openssl-3/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)) diff --git a/libs/openssl-3/crypto/rsa/rsa_local.h b/libs/openssl-3/crypto/rsa/rsa_local.h index ea70da05a..db9eb2a1d 100644 --- a/libs/openssl-3/crypto/rsa/rsa_local.h +++ b/libs/openssl-3/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); diff --git a/libs/openssl-3/crypto/rsa/rsa_sp800_56b_check.c b/libs/openssl-3/crypto/rsa/rsa_sp800_56b_check.c index 8bcfd89ef..b9aafdfe6 100644 --- a/libs/openssl-3/crypto/rsa/rsa_sp800_56b_check.c +++ b/libs/openssl-3/crypto/rsa/rsa_sp800_56b_check.c @@ -12,7 +12,6 @@ #include #include "crypto/bn.h" #include "rsa_local.h" -#include "../bn/bn_local.h" // WINSCP /* * Part of the RSA keypair test. diff --git a/libs/openssl-3/crypto/rsa/rsa_sp800_56b_gen.c b/libs/openssl-3/crypto/rsa/rsa_sp800_56b_gen.c index 9fa85bfdf..b0d9104b7 100644 --- a/libs/openssl-3/crypto/rsa/rsa_sp800_56b_gen.c +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/crypto/sha/keccak1600-x86_64.asm b/libs/openssl-3/crypto/sha/keccak1600-x86_64.asm index 979a8ac43..e671cf6f0 100644 --- a/libs/openssl-3/crypto/sha/keccak1600-x86_64.asm +++ b/libs/openssl-3/crypto/sha/keccak1600-x86_64.asm @@ -436,6 +436,7 @@ $L$SEH_begin_SHA3_squeeze: mov rsi,rdx mov rdx,r8 mov rcx,r9 + mov r8,QWORD[40+rsp] @@ -447,10 +448,12 @@ $L$SEH_begin_SHA3_squeeze: shr rcx,3 - mov r8,rdi + mov r9,rdi mov r12,rsi mov r13,rdx mov r14,rcx + bt r8d,0 + jc NEAR $L$next_block jmp NEAR $L$oop_squeeze ALIGN 32 @@ -458,8 +461,8 @@ $L$oop_squeeze: cmp r13,8 jb NEAR $L$tail_squeeze - mov rax,QWORD[r8] - lea r8,[8+r8] + mov rax,QWORD[r9] + lea r9,[8+r9] mov QWORD[r12],rax lea r12,[8+r12] sub r13,8 @@ -467,14 +470,14 @@ $L$oop_squeeze: sub rcx,1 jnz NEAR $L$oop_squeeze - +$L$next_block: call KeccakF1600 - mov r8,rdi + mov r9,rdi mov rcx,r14 jmp NEAR $L$oop_squeeze $L$tail_squeeze: - mov rsi,r8 + mov rsi,r9 mov rdi,r12 mov rcx,r13 DB 0xf3,0xa4 diff --git a/libs/openssl-3/crypto/sha/keccak1600.c b/libs/openssl-3/crypto/sha/keccak1600.c index c15bc42aa..6682367be 100644 --- a/libs/openssl-3/crypto/sha/keccak1600.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/sha/sha256.c b/libs/openssl-3/crypto/sha/sha256.c index 4017137c2..6ef218e86 100644 --- a/libs/openssl-3/crypto/sha/sha256.c +++ b/libs/openssl-3/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]; diff --git a/libs/openssl-3/crypto/sha/sha3.c b/libs/openssl-3/crypto/sha/sha3.c index 633bc2e12..2411b3f1f 100644 --- a/libs/openssl-3/crypto/sha/sha3.c +++ b/libs/openssl-3/crypto/sha/sha3.c @@ -10,12 +10,13 @@ #include #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; } diff --git a/libs/openssl-3/crypto/sha/sha512.c b/libs/openssl-3/crypto/sha/sha512.c index ee00b55de..bc547d7cd 100644 --- a/libs/openssl-3/crypto/sha/sha512.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/sha/sha_riscv.c b/libs/openssl-3/crypto/sha/sha_riscv.c new file mode 100644 index 000000000..c4a77a3d0 --- /dev/null +++ b/libs/openssl-3/crypto/sha/sha_riscv.c @@ -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 + */ + +#include +#include + +#include +#include +#include "crypto/riscv_arch.h" + +void sha256_block_data_order_zvkb_zvknha_or_zvknhb(void *ctx, const void *in, + size_t num); +void sha256_block_data_order_c(void *ctx, const void *in, size_t num); +void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num); + +void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num) +{ + if (RISCV_HAS_ZVKB() && (RISCV_HAS_ZVKNHA() || RISCV_HAS_ZVKNHB()) && + riscv_vlen() >= 128) { + sha256_block_data_order_zvkb_zvknha_or_zvknhb(ctx, in, num); + } else { + sha256_block_data_order_c(ctx, in, num); + } +} + +void sha512_block_data_order_zvkb_zvknhb(void *ctx, const void *in, size_t num); +void sha512_block_data_order_c(void *ctx, const void *in, size_t num); +void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num); + +void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num) +{ + if (RISCV_HAS_ZVKB_AND_ZVKNHB() && riscv_vlen() >= 128) { + sha512_block_data_order_zvkb_zvknhb(ctx, in, num); + } else { + sha512_block_data_order_c(ctx, in, num); + } +} diff --git a/libs/openssl-3/crypto/sleep.c b/libs/openssl-3/crypto/sleep.c index dc97d4edc..73467fb85 100644 --- a/libs/openssl-3/crypto/sleep.c +++ b/libs/openssl-3/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 } diff --git a/libs/openssl-3/crypto/sm2/sm2_crypt.c b/libs/openssl-3/crypto/sm2/sm2_crypt.c index f061772d5..b7303af52 100644 --- a/libs/openssl-3/crypto/sm2/sm2_crypt.c +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/crypto/sm3/sm3_local.h b/libs/openssl-3/crypto/sm3/sm3_local.h index 101e15c19..d2845f967 100644 --- a/libs/openssl-3/crypto/sm3/sm3_local.h +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/crypto/sm3/sm3_riscv.c b/libs/openssl-3/crypto/sm3/sm3_riscv.c new file mode 100644 index 000000000..21ee3772b --- /dev/null +++ b/libs/openssl-3/crypto/sm3/sm3_riscv.c @@ -0,0 +1,29 @@ +/* + * 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 + */ + +#include +#include + +#include +#include "internal/sm3.h" +#include "crypto/riscv_arch.h" +#include + +void ossl_hwsm3_block_data_order_zvksh(SM3_CTX *c, const void *p, size_t num); +void ossl_sm3_block_data_order(SM3_CTX *c, const void *p, size_t num); +void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num); + +void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num) +{ + if (RISCV_HAS_ZVKB_AND_ZVKSH() && riscv_vlen() >= 128) { + ossl_hwsm3_block_data_order_zvksh(c, p, num); + } else { + ossl_sm3_block_data_order(c, p, num); + } +} diff --git a/libs/openssl-3/crypto/srp/srp_lib.c b/libs/openssl-3/crypto/srp/srp_lib.c index e104f37bf..df0d3720f 100644 --- a/libs/openssl-3/crypto/srp/srp_lib.c +++ b/libs/openssl-3/crypto/srp/srp_lib.c @@ -20,7 +20,6 @@ # include # include # include "crypto/bn_srp.h" -# include "../crypto/bn/bn_local.h" /* calculate = SHA1(PAD(x) || PAD(y)) */ diff --git a/libs/openssl-3/crypto/stack/stack.c b/libs/openssl-3/crypto/stack/stack.c index 72e3087e8..e81398962 100644 --- a/libs/openssl-3/crypto/stack/stack.c +++ b/libs/openssl-3/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); } diff --git a/libs/openssl-3/crypto/thread/arch/thread_win.c b/libs/openssl-3/crypto/thread/arch/thread_win.c index d0ad8904e..fc0c21477 100644 --- a/libs/openssl-3/crypto/thread/arch/thread_win.c +++ b/libs/openssl-3/crypto/thread/arch/thread_win.c @@ -591,11 +591,9 @@ void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv) # endif -#ifndef WINSCP void ossl_crypto_mem_barrier(void) { MemoryBarrier(); } -#endif #endif diff --git a/libs/openssl-3/crypto/threads_none.c b/libs/openssl-3/crypto/threads_none.c index 580e5345d..c57c59bde 100644 --- a/libs/openssl-3/crypto/threads_none.c +++ b/libs/openssl-3/crypto/threads_none.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 @@ -9,6 +9,8 @@ #include #include "internal/cryptlib.h" +#include "internal/rcu.h" +#include "rcu_internal.h" #if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG) @@ -17,6 +19,82 @@ # include # endif +struct rcu_lock_st { + struct rcu_cb_item *cb_items; +}; + +CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers) +{ + struct rcu_lock_st *lock; + + lock = OPENSSL_zalloc(sizeof(*lock)); + return lock; +} + +void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock) +{ + OPENSSL_free(lock); +} + +void ossl_rcu_read_lock(CRYPTO_RCU_LOCK *lock) +{ + return; +} + +void ossl_rcu_write_lock(CRYPTO_RCU_LOCK *lock) +{ + return; +} + +void ossl_rcu_write_unlock(CRYPTO_RCU_LOCK *lock) +{ + return; +} + +void ossl_rcu_read_unlock(CRYPTO_RCU_LOCK *lock) +{ + return; +} + +void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock) +{ + struct rcu_cb_item *items = lock->cb_items; + struct rcu_cb_item *tmp; + + lock->cb_items = NULL; + + while (items != NULL) { + tmp = items->next; + items->fn(items->data); + OPENSSL_free(items); + items = tmp; + } +} + +int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data) +{ + struct rcu_cb_item *new = OPENSSL_zalloc(sizeof(*new)); + + if (new == NULL) + return 0; + + new->fn = cb; + new->data = data; + new->next = lock->cb_items; + lock->cb_items = new; + return 1; +} + +void *ossl_rcu_uptr_deref(void **p) +{ + return (void *)*p; +} + +void ossl_rcu_assign_uptr(void **p, void **v) +{ + *(void **)p = *(void **)v; +} + CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) { CRYPTO_RWLOCK *lock; diff --git a/libs/openssl-3/crypto/threads_pthread.c b/libs/openssl-3/crypto/threads_pthread.c index 59ddcdbff..92346e168 100644 --- a/libs/openssl-3/crypto/threads_pthread.c +++ b/libs/openssl-3/crypto/threads_pthread.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 @@ -11,7 +11,10 @@ #define OPENSSL_SUPPRESS_DEPRECATED #include +#include #include "internal/cryptlib.h" +#include "internal/rcu.h" +#include "rcu_internal.h" #if defined(__sun) # include @@ -26,7 +29,7 @@ * * See: https://github.com/llvm/llvm-project/commit/a4c2602b714e6c6edb98164550a5ae829b2de760 */ -#define BROKEN_CLANG_ATOMICS +# define BROKEN_CLANG_ATOMICS #endif #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS) @@ -34,7 +37,7 @@ # if defined(OPENSSL_SYS_UNIX) # include # include -#endif +# endif # include @@ -42,12 +45,648 @@ # define USE_RWLOCK # endif +/* + * For all GNU/clang atomic builtins, we also need fallbacks, to cover all + * other compilers. + + * Unfortunately, we can't do that with some "generic type", because there's no + * guarantee that the chosen generic type is large enough to cover all cases. + * Therefore, we implement fallbacks for each applicable type, with composed + * names that include the type they handle. + * + * (an anecdote: we previously tried to use |void *| as the generic type, with + * the thought that the pointer itself is the largest type. However, this is + * not true on 32-bit pointer platforms, as a |uint64_t| is twice as large) + * + * All applicable ATOMIC_ macros take the intended type as first parameter, so + * they can map to the correct fallback function. In the GNU/clang case, that + * parameter is simply ignored. + */ + +/* + * Internal types used with the ATOMIC_ macros, to make it possible to compose + * fallback function names. + */ +typedef void *pvoid; +typedef struct rcu_cb_item *prcu_cb_item; + +# if defined(__GNUC__) && defined(__ATOMIC_ACQUIRE) && !defined(BROKEN_CLANG_ATOMICS) \ + && !defined(USE_ATOMIC_FALLBACKS) +# if defined(__APPLE__) && defined(__clang__) && defined(__aarch64__) +/* + * For pointers, Apple M1 virtualized cpu seems to have some problem using the + * ldapr instruction (see https://github.com/openssl/openssl/pull/23974) + * When using the native apple clang compiler, this instruction is emitted for + * atomic loads, which is bad. So, if + * 1) We are building on a target that defines __APPLE__ AND + * 2) We are building on a target using clang (__clang__) AND + * 3) We are building for an M1 processor (__aarch64__) + * Then we shold not use __atomic_load_n and instead implement our own + * function to issue the ldar instruction instead, which procuces the proper + * sequencing guarantees + */ +static inline void *apple_atomic_load_n_pvoid(void **p, + ossl_unused int memorder) +{ + void *ret; + + __asm volatile("ldar %0, [%1]" : "=r" (ret): "r" (p):); + + return ret; +} + +/* For uint64_t, we should be fine, though */ +# define apple_atomic_load_n_uint64_t(p, o) __atomic_load_n(p, o) + +# define ATOMIC_LOAD_N(t, p, o) apple_atomic_load_n_##t(p, o) +# else +# define ATOMIC_LOAD_N(t, p, o) __atomic_load_n(p, o) +# endif +# define ATOMIC_STORE_N(t, p, v, o) __atomic_store_n(p, v, o) +# define ATOMIC_STORE(t, p, v, o) __atomic_store(p, v, o) +# define ATOMIC_EXCHANGE_N(t, p, v, o) __atomic_exchange_n(p, v, o) +# define ATOMIC_ADD_FETCH(p, v, o) __atomic_add_fetch(p, v, o) +# define ATOMIC_FETCH_ADD(p, v, o) __atomic_fetch_add(p, v, o) +# define ATOMIC_SUB_FETCH(p, v, o) __atomic_sub_fetch(p, v, o) +# define ATOMIC_AND_FETCH(p, m, o) __atomic_and_fetch(p, m, o) +# define ATOMIC_OR_FETCH(p, m, o) __atomic_or_fetch(p, m, o) +# else +static pthread_mutex_t atomic_sim_lock = PTHREAD_MUTEX_INITIALIZER; + +# define IMPL_fallback_atomic_load_n(t) \ + static ossl_inline t fallback_atomic_load_n_##t(t *p) \ + { \ + t ret; \ + \ + pthread_mutex_lock(&atomic_sim_lock); \ + ret = *p; \ + pthread_mutex_unlock(&atomic_sim_lock); \ + return ret; \ + } +IMPL_fallback_atomic_load_n(uint64_t) +IMPL_fallback_atomic_load_n(pvoid) + +# define ATOMIC_LOAD_N(t, p, o) fallback_atomic_load_n_##t(p) + +# define IMPL_fallback_atomic_store_n(t) \ + static ossl_inline t fallback_atomic_store_n_##t(t *p, t v) \ + { \ + t ret; \ + \ + pthread_mutex_lock(&atomic_sim_lock); \ + ret = *p; \ + *p = v; \ + pthread_mutex_unlock(&atomic_sim_lock); \ + return ret; \ + } +IMPL_fallback_atomic_store_n(uint64_t) + +# define ATOMIC_STORE_N(t, p, v, o) fallback_atomic_store_n_##t(p, v) + +# define IMPL_fallback_atomic_store(t) \ + static ossl_inline void fallback_atomic_store_##t(t *p, t *v) \ + { \ + pthread_mutex_lock(&atomic_sim_lock); \ + *p = *v; \ + pthread_mutex_unlock(&atomic_sim_lock); \ + } +IMPL_fallback_atomic_store(uint64_t) +IMPL_fallback_atomic_store(pvoid) + +# define ATOMIC_STORE(t, p, v, o) fallback_atomic_store_##t(p, v) + +# define IMPL_fallback_atomic_exchange_n(t) \ + static ossl_inline t fallback_atomic_exchange_n_##t(t *p, t v) \ + { \ + t ret; \ + \ + pthread_mutex_lock(&atomic_sim_lock); \ + ret = *p; \ + *p = v; \ + pthread_mutex_unlock(&atomic_sim_lock); \ + return ret; \ + } +IMPL_fallback_atomic_exchange_n(uint64_t) +IMPL_fallback_atomic_exchange_n(prcu_cb_item) + +# define ATOMIC_EXCHANGE_N(t, p, v, o) fallback_atomic_exchange_n_##t(p, v) + +/* + * The fallbacks that follow don't need any per type implementation, as + * they are designed for uint64_t only. If there comes a time when multiple + * types need to be covered, it's relatively easy to refactor them the same + * way as the fallbacks above. + */ + +static ossl_inline uint64_t fallback_atomic_add_fetch(uint64_t *p, uint64_t v) +{ + uint64_t ret; + + pthread_mutex_lock(&atomic_sim_lock); + *p += v; + ret = *p; + pthread_mutex_unlock(&atomic_sim_lock); + return ret; +} + +# define ATOMIC_ADD_FETCH(p, v, o) fallback_atomic_add_fetch(p, v) + +static ossl_inline uint64_t fallback_atomic_fetch_add(uint64_t *p, uint64_t v) +{ + uint64_t ret; + + pthread_mutex_lock(&atomic_sim_lock); + ret = *p; + *p += v; + pthread_mutex_unlock(&atomic_sim_lock); + return ret; +} + +# define ATOMIC_FETCH_ADD(p, v, o) fallback_atomic_fetch_add(p, v) + +static ossl_inline uint64_t fallback_atomic_sub_fetch(uint64_t *p, uint64_t v) +{ + uint64_t ret; + + pthread_mutex_lock(&atomic_sim_lock); + *p -= v; + ret = *p; + pthread_mutex_unlock(&atomic_sim_lock); + return ret; +} + +# define ATOMIC_SUB_FETCH(p, v, o) fallback_atomic_sub_fetch(p, v) + +static ossl_inline uint64_t fallback_atomic_and_fetch(uint64_t *p, uint64_t m) +{ + uint64_t ret; + + pthread_mutex_lock(&atomic_sim_lock); + *p &= m; + ret = *p; + pthread_mutex_unlock(&atomic_sim_lock); + return ret; +} + +# define ATOMIC_AND_FETCH(p, v, o) fallback_atomic_and_fetch(p, v) + +static ossl_inline uint64_t fallback_atomic_or_fetch(uint64_t *p, uint64_t m) +{ + uint64_t ret; + + pthread_mutex_lock(&atomic_sim_lock); + *p |= m; + ret = *p; + pthread_mutex_unlock(&atomic_sim_lock); + return ret; +} + +# define ATOMIC_OR_FETCH(p, v, o) fallback_atomic_or_fetch(p, v) +# endif + +static CRYPTO_THREAD_LOCAL rcu_thr_key; + +/* + * users is broken up into 2 parts + * bits 0-15 current readers + * bit 32-63 - ID + */ +# define READER_SHIFT 0 +# define ID_SHIFT 32 +# define READER_SIZE 16 +# define ID_SIZE 32 + +# define READER_MASK (((uint64_t)1 << READER_SIZE) - 1) +# define ID_MASK (((uint64_t)1 << ID_SIZE) - 1) +# define READER_COUNT(x) (((uint64_t)(x) >> READER_SHIFT) & READER_MASK) +# define ID_VAL(x) (((uint64_t)(x) >> ID_SHIFT) & ID_MASK) +# define VAL_READER ((uint64_t)1 << READER_SHIFT) +# define VAL_ID(x) ((uint64_t)x << ID_SHIFT) + +/* + * This is the core of an rcu lock. It tracks the readers and writers for the + * current quiescence point for a given lock. Users is the 64 bit value that + * stores the READERS/ID as defined above + * + */ +struct rcu_qp { + uint64_t 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 { + /* Callbacks to call for next ossl_synchronize_rcu */ + struct rcu_cb_item *cb_items; + + /* rcu generation counter for in-order retirement */ + uint32_t id_ctr; + + /* Array of quiescent points for synchronization */ + struct rcu_qp *qp_group; + + /* Number of elements in qp_group array */ + size_t group_count; + + /* Index of the current qp in the qp_group array */ + uint64_t reader_idx; + + /* value of the next id_ctr value to be retired */ + uint32_t next_to_retire; + + /* index of the next free rcu_qp in the qp_group */ + uint64_t current_alloc_idx; + + /* number of qp's in qp_group array currently being retired */ + uint32_t writers_alloced; + + /* lock protecting write side operations */ + pthread_mutex_t write_lock; + + /* lock protecting updates to writers_alloced/current_alloc_idx */ + pthread_mutex_t alloc_lock; + + /* signal to wake threads waiting on alloc_lock */ + pthread_cond_t alloc_signal; + + /* lock to enforce in-order retirement */ + pthread_mutex_t prior_lock; + + /* signal to wake threads waiting on prior_lock */ + pthread_cond_t 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); +} + +/* Read side acquisition of the current qp */ +static struct rcu_qp *get_hold_current_qp(struct rcu_lock_st *lock) +{ + uint64_t qp_idx; + + /* get the current qp index */ + for (;;) { + /* + * Notes on use of __ATOMIC_ACQUIRE + * We need to ensure the following: + * 1) That subsequent operations aren't optimized by hoisting them above + * this operation. Specifically, we don't want the below re-load of + * qp_idx to get optimized away + * 2) We want to ensure that any updating of reader_idx on the write side + * of the lock is flushed from a local cpu cache so that we see any + * updates prior to the load. This is a non-issue on cache coherent + * systems like x86, but is relevant on other arches + * Note: This applies to the reload below as well + */ + qp_idx = ATOMIC_LOAD_N(uint64_t, &lock->reader_idx, __ATOMIC_ACQUIRE); + + /* + * Notes of use of __ATOMIC_RELEASE + * This counter is only read by the write side of the lock, and so we + * specify __ATOMIC_RELEASE here to ensure that the write side of the + * lock see this during the spin loop read of users, as it waits for the + * reader count to approach zero + */ + ATOMIC_ADD_FETCH(&lock->qp_group[qp_idx].users, VAL_READER, + __ATOMIC_RELEASE); + + /* if the idx hasn't changed, we're good, else try again */ + if (qp_idx == ATOMIC_LOAD_N(uint64_t, &lock->reader_idx, __ATOMIC_ACQUIRE)) + break; + + /* + * Notes on use of __ATOMIC_RELEASE + * As with the add above, we want to ensure that this decrement is + * seen by the write side of the lock as soon as it happens to prevent + * undue spinning waiting for write side completion + */ + ATOMIC_SUB_FETCH(&lock->qp_group[qp_idx].users, VAL_READER, + __ATOMIC_RELEASE); + } + + return &lock->qp_group[qp_idx]; +} + +void ossl_rcu_read_lock(CRYPTO_RCU_LOCK *lock) +{ + struct rcu_thr_data *data; + int i, 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); + ossl_init_thread_start(NULL, NULL, free_rcu_thr_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) { + data->thread_qps[i].depth++; + 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_read_unlock(CRYPTO_RCU_LOCK *lock) +{ + int i; + struct rcu_thr_data *data = CRYPTO_THREAD_get_local(&rcu_thr_key); + uint64_t ret; + + assert(data != NULL); + + for (i = 0; i < MAX_QPS; i++) { + if (data->thread_qps[i].lock == lock) { + /* + * As with read side acquisition, we use __ATOMIC_RELEASE here + * to ensure that the decrement is published immediately + * to any write side waiters + */ + data->thread_qps[i].depth--; + if (data->thread_qps[i].depth == 0) { + ret = ATOMIC_SUB_FETCH(&data->thread_qps[i].qp->users, VAL_READER, + __ATOMIC_RELEASE); + OPENSSL_assert(ret != UINT64_MAX); + data->thread_qps[i].qp = NULL; + data->thread_qps[i].lock = NULL; + } + return; + } + } + /* + * If we get here, we're trying to unlock a lock that we never acquired - + * that's fatal. + */ + assert(0); +} + +/* + * Write side allocation routine to get the current qp + * and replace it with a new one + */ +static struct rcu_qp *update_qp(CRYPTO_RCU_LOCK *lock) +{ + uint64_t new_id; + uint64_t current_idx; + + pthread_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) + /* we have to wait for one to be free */ + pthread_cond_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); + /* + * Even though we are under a write side lock here + * We need to use atomic instructions to ensure that the results + * of this update are published to the read side prior to updating the + * reader idx below + */ + ATOMIC_AND_FETCH(&lock->qp_group[current_idx].users, ID_MASK, + __ATOMIC_RELEASE); + ATOMIC_OR_FETCH(&lock->qp_group[current_idx].users, new_id, + __ATOMIC_RELEASE); + + /* + * Update the reader index to be the prior qp. + * Note the use of __ATOMIC_RELEASE here is based on the corresponding use + * of __ATOMIC_ACQUIRE in get_hold_current_qp, as we want any publication + * of this value to be seen on the read side immediately after it happens + */ + ATOMIC_STORE_N(uint64_t, &lock->reader_idx, lock->current_alloc_idx, + __ATOMIC_RELEASE); + + /* wake up any waiters */ + pthread_cond_signal(&lock->alloc_signal); + pthread_mutex_unlock(&lock->alloc_lock); + return &lock->qp_group[current_idx]; +} + +static void retire_qp(CRYPTO_RCU_LOCK *lock, struct rcu_qp *qp) +{ + pthread_mutex_lock(&lock->alloc_lock); + lock->writers_alloced--; + pthread_cond_signal(&lock->alloc_signal); + pthread_mutex_unlock(&lock->alloc_lock); +} + +static struct rcu_qp *allocate_new_qp_group(CRYPTO_RCU_LOCK *lock, + int count) +{ + struct rcu_qp *new = + OPENSSL_zalloc(sizeof(*new) * count); + + lock->group_count = count; + return new; +} + +void ossl_rcu_write_lock(CRYPTO_RCU_LOCK *lock) +{ + pthread_mutex_lock(&lock->write_lock); +} + +void ossl_rcu_write_unlock(CRYPTO_RCU_LOCK *lock) +{ + pthread_mutex_unlock(&lock->write_lock); +} + +void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock) +{ + struct rcu_qp *qp; + uint64_t count; + struct rcu_cb_item *cb_items, *tmpcb; + + /* + * __ATOMIC_ACQ_REL is used here to ensure that we get any prior published + * writes before we read, and publish our write immediately + */ + cb_items = ATOMIC_EXCHANGE_N(prcu_cb_item, &lock->cb_items, NULL, + __ATOMIC_ACQ_REL); + + qp = update_qp(lock); + + /* + * wait for the reader count to reach zero + * Note the use of __ATOMIC_ACQUIRE here to ensure that any + * prior __ATOMIC_RELEASE write operation in get_hold_current_qp + * is visible prior to our read + */ + do { + count = ATOMIC_LOAD_N(uint64_t, &qp->users, __ATOMIC_ACQUIRE); + } while (READER_COUNT(count) != 0); + + /* retire in order */ + pthread_mutex_lock(&lock->prior_lock); + while (lock->next_to_retire != ID_VAL(count)) + pthread_cond_wait(&lock->prior_signal, &lock->prior_lock); + lock->next_to_retire++; + pthread_cond_broadcast(&lock->prior_signal); + pthread_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); + } +} + +int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data) +{ + struct rcu_cb_item *new = + OPENSSL_zalloc(sizeof(*new)); + + if (new == NULL) + return 0; + + new->data = data; + new->fn = cb; + /* + * Use __ATOMIC_ACQ_REL here to indicate that any prior writes to this + * list are visible to us prior to reading, and publish the new value + * immediately + */ + new->next = ATOMIC_EXCHANGE_N(prcu_cb_item, &lock->cb_items, new, + __ATOMIC_ACQ_REL); + + return 1; +} + +void *ossl_rcu_uptr_deref(void **p) +{ + return ATOMIC_LOAD_N(pvoid, p, __ATOMIC_ACQUIRE); +} + +void ossl_rcu_assign_uptr(void **p, void **v) +{ + ATOMIC_STORE(pvoid, p, v, __ATOMIC_RELEASE); +} + +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; + + pthread_mutex_init(&new->write_lock, NULL); + pthread_mutex_init(&new->prior_lock, NULL); + pthread_mutex_init(&new->alloc_lock, NULL); + pthread_cond_init(&new->prior_signal, NULL); + pthread_cond_init(&new->alloc_signal, NULL); + new->qp_group = allocate_new_qp_group(new, num_writers + 1); + if (new->qp_group == NULL) { + OPENSSL_free(new); + new = NULL; + } + return new; +} + +void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock) +{ + struct rcu_lock_st *rlock = (struct rcu_lock_st *)lock; + + if (lock == NULL) + return; + + /* make sure we're synchronized */ + ossl_synchronize_rcu(rlock); + + OPENSSL_free(rlock->qp_group); + /* There should only be a single qp left now */ + OPENSSL_free(rlock); +} + CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) { # ifdef USE_RWLOCK CRYPTO_RWLOCK *lock; - if ((lock = CRYPTO_zalloc(sizeof(pthread_rwlock_t), NULL, 0)) == NULL) + if ((lock = OPENSSL_zalloc(sizeof(pthread_rwlock_t))) == NULL) /* Don't set error, to avoid recursion blowup. */ return NULL; @@ -59,7 +698,7 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) pthread_mutexattr_t attr; CRYPTO_RWLOCK *lock; - if ((lock = CRYPTO_zalloc(sizeof(pthread_mutex_t), NULL, 0)) == NULL) + if ((lock = OPENSSL_zalloc(sizeof(pthread_mutex_t))) == NULL) /* Don't set error, to avoid recursion blowup. */ return NULL; diff --git a/libs/openssl-3/crypto/threads_win.c b/libs/openssl-3/crypto/threads_win.c index 7ae877e54..64354dc42 100644 --- a/libs/openssl-3/crypto/threads_win.c +++ b/libs/openssl-3/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 @@ -10,9 +10,10 @@ #if defined(_WIN32) # include # if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 -// WINSCP # define USE_RWLOCK +# define USE_RWLOCK # endif #endif +#include /* * VC++ 2008 or earlier x86 compilers do not have an inline implementation @@ -27,6 +28,11 @@ #endif #include +#include +#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; diff --git a/libs/openssl-3/crypto/x509/t_req.c b/libs/openssl-3/crypto/x509/t_req.c index fe62a0870..63626c0d9 100644 --- a/libs/openssl-3/crypto/x509/t_req.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/x509/t_x509.c b/libs/openssl-3/crypto/x509/t_x509.c index 3fc07e614..192998d45 100644 --- a/libs/openssl-3/crypto/x509/t_x509.c +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/crypto/x509/v3_addr.c b/libs/openssl-3/crypto/x509/v3_addr.c index 99079472a..d0e5f9efe 100644 --- a/libs/openssl-3/crypto/x509/v3_addr.c +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/crypto/x509/v3_ist.c b/libs/openssl-3/crypto/x509/v3_ist.c index 1e37b3b08..b7ce4bb91 100644 --- a/libs/openssl-3/crypto/x509/v3_ist.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/crypto/x509/x509_lu.c b/libs/openssl-3/crypto/x509/x509_lu.c index 0ca7cb960..e7fdf3d6a 100644 --- a/libs/openssl-3/crypto/x509/x509_lu.c +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/include/crypto/aes_platform.h b/libs/openssl-3/include/crypto/aes_platform.h index a7cae5d46..bb0c10ec8 100644 --- a/libs/openssl-3/include/crypto/aes_platform.h +++ b/libs/openssl-3/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]); diff --git a/libs/openssl-3/include/crypto/bn_conf.h b/libs/openssl-3/include/crypto/bn_conf.h index c87cbc4ba..7ac6eb2df 100644 --- a/libs/openssl-3/include/crypto/bn_conf.h +++ b/libs/openssl-3/include/crypto/bn_conf.h @@ -22,8 +22,20 @@ /* Should we define BN_DIV2W here? */ /* Only one for the following should be defined */ +#if defined(_WIN64) || defined(OPENSSL_SYS_WIN64) || defined(_M_ARM64) +#undef SIXTY_FOUR_BIT_LONG +#define SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT + +#else + +#if defined(_WIN32) || defined(OPENSSL_SYS_WIN32) #undef SIXTY_FOUR_BIT_LONG #undef SIXTY_FOUR_BIT #define THIRTY_TWO_BIT #endif + +#endif + +#endif diff --git a/libs/openssl-3/include/crypto/chacha.h b/libs/openssl-3/include/crypto/chacha.h index d29998ffe..2af2c2ecf 100644 --- a/libs/openssl-3/include/crypto/chacha.h +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/include/crypto/dsa.h b/libs/openssl-3/include/crypto/dsa.h index 85d92a18c..b08a42c7f 100644 --- a/libs/openssl-3/include/crypto/dsa.h +++ b/libs/openssl-3/include/crypto/dsa.h @@ -15,6 +15,11 @@ # include # 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 diff --git a/libs/openssl-3/include/crypto/evp.h b/libs/openssl-3/include/crypto/evp.h index 34cea2f9f..50ad737fc 100644 --- a/libs/openssl-3/include/crypto/evp.h +++ b/libs/openssl-3/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); diff --git a/libs/openssl-3/include/crypto/httperr.h b/libs/openssl-3/include/crypto/httperr.h index 969df17b8..827d61a23 100644 --- a/libs/openssl-3/include/crypto/httperr.h +++ b/libs/openssl-3/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 } diff --git a/libs/openssl-3/include/crypto/riscv_arch.def b/libs/openssl-3/include/crypto/riscv_arch.def index 6c26dbf40..70b0647ae 100644 --- a/libs/openssl-3/include/crypto/riscv_arch.def +++ b/libs/openssl-3/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 ... diff --git a/libs/openssl-3/include/crypto/riscv_arch.h b/libs/openssl-3/include/crypto/riscv_arch.h index 951858411..6950137f4 100644 --- a/libs/openssl-3/include/crypto/riscv_arch.h +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/include/crypto/rsa.h b/libs/openssl-3/include/crypto/rsa.h index 8eddc168f..592efdb7f 100644 --- a/libs/openssl-3/include/crypto/rsa.h +++ b/libs/openssl-3/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); diff --git a/libs/openssl-3/include/crypto/sm4_platform.h b/libs/openssl-3/include/crypto/sm4_platform.h index cc4f51425..928dc17ff 100644 --- a/libs/openssl-3/include/crypto/sm4_platform.h +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/include/internal/common.h b/libs/openssl-3/include/internal/common.h index 15666f111..b176a2749 100644 --- a/libs/openssl-3/include/internal/common.h +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/include/internal/json_enc.h b/libs/openssl-3/include/internal/json_enc.h new file mode 100644 index 000000000..e7d9a6d92 --- /dev/null +++ b/libs/openssl-3/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 + +/* + * 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 diff --git a/libs/openssl-3/include/internal/list.h b/libs/openssl-3/include/internal/list.h index fdd356c40..902047641 100644 --- a/libs/openssl-3/include/internal/list.h +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/include/internal/param_names.h b/libs/openssl-3/include/internal/param_names.h index eb24641ca..dc37f4363 100644 --- a/libs/openssl-3/include/internal/param_names.h +++ b/libs/openssl-3/include/internal/param_names.h @@ -14,7 +14,7 @@ int ossl_param_find_pidx(const char *s); /* Parameter name definitions - generated by util/perl/OpenSSL/paramnames.pm */ -#define NUM_PIDX 290 +#define NUM_PIDX 291 #define PIDX_ALG_PARAM_CIPHER 0 #define PIDX_ALG_PARAM_DIGEST 1 @@ -291,86 +291,87 @@ int ossl_param_find_pidx(const char *s); #define PIDX_PKEY_PARAM_RSA_COEFFICIENT8 221 #define PIDX_PKEY_PARAM_RSA_COEFFICIENT9 222 #define PIDX_PKEY_PARAM_RSA_D 223 +#define PIDX_PKEY_PARAM_RSA_DERIVE_FROM_PQ 224 #define PIDX_PKEY_PARAM_RSA_DIGEST PIDX_PKEY_PARAM_DIGEST #define PIDX_PKEY_PARAM_RSA_DIGEST_PROPS PIDX_PKEY_PARAM_PROPERTIES -#define PIDX_PKEY_PARAM_RSA_E 224 -#define PIDX_PKEY_PARAM_RSA_EXPONENT 225 -#define PIDX_PKEY_PARAM_RSA_EXPONENT1 226 -#define PIDX_PKEY_PARAM_RSA_EXPONENT10 227 -#define PIDX_PKEY_PARAM_RSA_EXPONENT2 228 -#define PIDX_PKEY_PARAM_RSA_EXPONENT3 229 -#define PIDX_PKEY_PARAM_RSA_EXPONENT4 230 -#define PIDX_PKEY_PARAM_RSA_EXPONENT5 231 -#define PIDX_PKEY_PARAM_RSA_EXPONENT6 232 -#define PIDX_PKEY_PARAM_RSA_EXPONENT7 233 -#define PIDX_PKEY_PARAM_RSA_EXPONENT8 234 -#define PIDX_PKEY_PARAM_RSA_EXPONENT9 235 -#define PIDX_PKEY_PARAM_RSA_FACTOR 236 -#define PIDX_PKEY_PARAM_RSA_FACTOR1 237 -#define PIDX_PKEY_PARAM_RSA_FACTOR10 238 -#define PIDX_PKEY_PARAM_RSA_FACTOR2 239 -#define PIDX_PKEY_PARAM_RSA_FACTOR3 240 -#define PIDX_PKEY_PARAM_RSA_FACTOR4 241 -#define PIDX_PKEY_PARAM_RSA_FACTOR5 242 -#define PIDX_PKEY_PARAM_RSA_FACTOR6 243 -#define PIDX_PKEY_PARAM_RSA_FACTOR7 244 -#define PIDX_PKEY_PARAM_RSA_FACTOR8 245 -#define PIDX_PKEY_PARAM_RSA_FACTOR9 246 +#define PIDX_PKEY_PARAM_RSA_E 225 +#define PIDX_PKEY_PARAM_RSA_EXPONENT 226 +#define PIDX_PKEY_PARAM_RSA_EXPONENT1 227 +#define PIDX_PKEY_PARAM_RSA_EXPONENT10 228 +#define PIDX_PKEY_PARAM_RSA_EXPONENT2 229 +#define PIDX_PKEY_PARAM_RSA_EXPONENT3 230 +#define PIDX_PKEY_PARAM_RSA_EXPONENT4 231 +#define PIDX_PKEY_PARAM_RSA_EXPONENT5 232 +#define PIDX_PKEY_PARAM_RSA_EXPONENT6 233 +#define PIDX_PKEY_PARAM_RSA_EXPONENT7 234 +#define PIDX_PKEY_PARAM_RSA_EXPONENT8 235 +#define PIDX_PKEY_PARAM_RSA_EXPONENT9 236 +#define PIDX_PKEY_PARAM_RSA_FACTOR 237 +#define PIDX_PKEY_PARAM_RSA_FACTOR1 238 +#define PIDX_PKEY_PARAM_RSA_FACTOR10 239 +#define PIDX_PKEY_PARAM_RSA_FACTOR2 240 +#define PIDX_PKEY_PARAM_RSA_FACTOR3 241 +#define PIDX_PKEY_PARAM_RSA_FACTOR4 242 +#define PIDX_PKEY_PARAM_RSA_FACTOR5 243 +#define PIDX_PKEY_PARAM_RSA_FACTOR6 244 +#define PIDX_PKEY_PARAM_RSA_FACTOR7 245 +#define PIDX_PKEY_PARAM_RSA_FACTOR8 246 +#define PIDX_PKEY_PARAM_RSA_FACTOR9 247 #define PIDX_PKEY_PARAM_RSA_MASKGENFUNC PIDX_PKEY_PARAM_MASKGENFUNC #define PIDX_PKEY_PARAM_RSA_MGF1_DIGEST PIDX_PKEY_PARAM_MGF1_DIGEST #define PIDX_PKEY_PARAM_RSA_N 129 -#define PIDX_PKEY_PARAM_RSA_PRIMES 247 -#define PIDX_PKEY_PARAM_RSA_PSS_SALTLEN 248 -#define PIDX_PKEY_PARAM_RSA_TEST_P1 249 -#define PIDX_PKEY_PARAM_RSA_TEST_P2 250 -#define PIDX_PKEY_PARAM_RSA_TEST_Q1 251 -#define PIDX_PKEY_PARAM_RSA_TEST_Q2 252 -#define PIDX_PKEY_PARAM_RSA_TEST_XP 253 -#define PIDX_PKEY_PARAM_RSA_TEST_XP1 254 -#define PIDX_PKEY_PARAM_RSA_TEST_XP2 255 -#define PIDX_PKEY_PARAM_RSA_TEST_XQ 256 -#define PIDX_PKEY_PARAM_RSA_TEST_XQ1 257 -#define PIDX_PKEY_PARAM_RSA_TEST_XQ2 258 -#define PIDX_PKEY_PARAM_SECURITY_BITS 259 +#define PIDX_PKEY_PARAM_RSA_PRIMES 248 +#define PIDX_PKEY_PARAM_RSA_PSS_SALTLEN 249 +#define PIDX_PKEY_PARAM_RSA_TEST_P1 250 +#define PIDX_PKEY_PARAM_RSA_TEST_P2 251 +#define PIDX_PKEY_PARAM_RSA_TEST_Q1 252 +#define PIDX_PKEY_PARAM_RSA_TEST_Q2 253 +#define PIDX_PKEY_PARAM_RSA_TEST_XP 254 +#define PIDX_PKEY_PARAM_RSA_TEST_XP1 255 +#define PIDX_PKEY_PARAM_RSA_TEST_XP2 256 +#define PIDX_PKEY_PARAM_RSA_TEST_XQ 257 +#define PIDX_PKEY_PARAM_RSA_TEST_XQ1 258 +#define PIDX_PKEY_PARAM_RSA_TEST_XQ2 259 +#define PIDX_PKEY_PARAM_SECURITY_BITS 260 #define PIDX_PKEY_PARAM_USE_COFACTOR_ECDH PIDX_PKEY_PARAM_USE_COFACTOR_FLAG -#define PIDX_PKEY_PARAM_USE_COFACTOR_FLAG 260 -#define PIDX_PROV_PARAM_BUILDINFO 261 -#define PIDX_PROV_PARAM_CORE_MODULE_FILENAME 262 -#define PIDX_PROV_PARAM_CORE_PROV_NAME 263 -#define PIDX_PROV_PARAM_CORE_VERSION 264 -#define PIDX_PROV_PARAM_DRBG_TRUNC_DIGEST 265 -#define PIDX_PROV_PARAM_NAME 266 -#define PIDX_PROV_PARAM_SECURITY_CHECKS 267 -#define PIDX_PROV_PARAM_SELF_TEST_DESC 268 -#define PIDX_PROV_PARAM_SELF_TEST_PHASE 269 -#define PIDX_PROV_PARAM_SELF_TEST_TYPE 270 -#define PIDX_PROV_PARAM_STATUS 271 -#define PIDX_PROV_PARAM_TLS1_PRF_EMS_CHECK 272 +#define PIDX_PKEY_PARAM_USE_COFACTOR_FLAG 261 +#define PIDX_PROV_PARAM_BUILDINFO 262 +#define PIDX_PROV_PARAM_CORE_MODULE_FILENAME 263 +#define PIDX_PROV_PARAM_CORE_PROV_NAME 264 +#define PIDX_PROV_PARAM_CORE_VERSION 265 +#define PIDX_PROV_PARAM_DRBG_TRUNC_DIGEST 266 +#define PIDX_PROV_PARAM_NAME 267 +#define PIDX_PROV_PARAM_SECURITY_CHECKS 268 +#define PIDX_PROV_PARAM_SELF_TEST_DESC 269 +#define PIDX_PROV_PARAM_SELF_TEST_PHASE 270 +#define PIDX_PROV_PARAM_SELF_TEST_TYPE 271 +#define PIDX_PROV_PARAM_STATUS 272 +#define PIDX_PROV_PARAM_TLS1_PRF_EMS_CHECK 273 #define PIDX_PROV_PARAM_VERSION 108 -#define PIDX_RAND_PARAM_GENERATE 273 -#define PIDX_RAND_PARAM_MAX_REQUEST 274 -#define PIDX_RAND_PARAM_STATE 275 -#define PIDX_RAND_PARAM_STRENGTH 276 -#define PIDX_RAND_PARAM_TEST_ENTROPY 277 -#define PIDX_RAND_PARAM_TEST_NONCE 278 -#define PIDX_SIGNATURE_PARAM_ALGORITHM_ID 279 -#define PIDX_SIGNATURE_PARAM_CONTEXT_STRING 280 +#define PIDX_RAND_PARAM_GENERATE 274 +#define PIDX_RAND_PARAM_MAX_REQUEST 275 +#define PIDX_RAND_PARAM_STATE 276 +#define PIDX_RAND_PARAM_STRENGTH 277 +#define PIDX_RAND_PARAM_TEST_ENTROPY 278 +#define PIDX_RAND_PARAM_TEST_NONCE 279 +#define PIDX_SIGNATURE_PARAM_ALGORITHM_ID 280 +#define PIDX_SIGNATURE_PARAM_CONTEXT_STRING 281 #define PIDX_SIGNATURE_PARAM_DIGEST PIDX_PKEY_PARAM_DIGEST #define PIDX_SIGNATURE_PARAM_DIGEST_SIZE PIDX_PKEY_PARAM_DIGEST_SIZE -#define PIDX_SIGNATURE_PARAM_INSTANCE 281 -#define PIDX_SIGNATURE_PARAM_KAT 282 +#define PIDX_SIGNATURE_PARAM_INSTANCE 282 +#define PIDX_SIGNATURE_PARAM_KAT 283 #define PIDX_SIGNATURE_PARAM_MGF1_DIGEST PIDX_PKEY_PARAM_MGF1_DIGEST #define PIDX_SIGNATURE_PARAM_MGF1_PROPERTIES PIDX_PKEY_PARAM_MGF1_PROPERTIES -#define PIDX_SIGNATURE_PARAM_NONCE_TYPE 283 +#define PIDX_SIGNATURE_PARAM_NONCE_TYPE 284 #define PIDX_SIGNATURE_PARAM_PAD_MODE PIDX_PKEY_PARAM_PAD_MODE #define PIDX_SIGNATURE_PARAM_PROPERTIES PIDX_PKEY_PARAM_PROPERTIES -#define PIDX_SIGNATURE_PARAM_PSS_SALTLEN 248 -#define PIDX_STORE_PARAM_ALIAS 284 +#define PIDX_SIGNATURE_PARAM_PSS_SALTLEN 249 +#define PIDX_STORE_PARAM_ALIAS 285 #define PIDX_STORE_PARAM_DIGEST 1 -#define PIDX_STORE_PARAM_EXPECT 285 -#define PIDX_STORE_PARAM_FINGERPRINT 286 -#define PIDX_STORE_PARAM_INPUT_TYPE 287 -#define PIDX_STORE_PARAM_ISSUER 266 +#define PIDX_STORE_PARAM_EXPECT 286 +#define PIDX_STORE_PARAM_FINGERPRINT 287 +#define PIDX_STORE_PARAM_INPUT_TYPE 288 +#define PIDX_STORE_PARAM_ISSUER 267 #define PIDX_STORE_PARAM_PROPERTIES 4 -#define PIDX_STORE_PARAM_SERIAL 288 -#define PIDX_STORE_PARAM_SUBJECT 289 +#define PIDX_STORE_PARAM_SERIAL 289 +#define PIDX_STORE_PARAM_SUBJECT 290 diff --git a/libs/openssl-3/include/internal/qlog.h b/libs/openssl-3/include/internal/qlog.h new file mode 100644 index 000000000..b81bfe7e4 --- /dev/null +++ b/libs/openssl-3/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 +# 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 diff --git a/libs/openssl-3/include/internal/qlog_event_helpers.h b/libs/openssl-3/include/internal/qlog_event_helpers.h new file mode 100644 index 000000000..43d623608 --- /dev/null +++ b/libs/openssl-3/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 +# 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 diff --git a/libs/openssl-3/include/internal/qlog_events.h b/libs/openssl-3/include/internal/qlog_events.h new file mode 100644 index 000000000..6dd44bf36 --- /dev/null +++ b/libs/openssl-3/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) diff --git a/libs/openssl-3/include/internal/quic_ackm.h b/libs/openssl-3/include/internal/quic_ackm.h index 03fc60886..69b862d9c 100644 --- a/libs/openssl-3/include/internal/quic_ackm.h +++ b/libs/openssl-3/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, diff --git a/libs/openssl-3/include/internal/quic_cc.h b/libs/openssl-3/include/internal/quic_cc.h index 60c710b0b..dbd439dd0 100644 --- a/libs/openssl-3/include/internal/quic_cc.h +++ b/libs/openssl-3/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; diff --git a/libs/openssl-3/include/internal/quic_cfq.h b/libs/openssl-3/include/internal/quic_cfq.h index 22c436dc0..56ebcb930 100644 --- a/libs/openssl-3/include/internal/quic_cfq.h +++ b/libs/openssl-3/include/internal/quic_cfq.h @@ -12,6 +12,7 @@ # include # 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); diff --git a/libs/openssl-3/include/internal/quic_channel.h b/libs/openssl-3/include/internal/quic_channel.h index f46db0637..3b373ab68 100644 --- a/libs/openssl-3/include/internal/quic_channel.h +++ b/libs/openssl-3/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 # 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 diff --git a/libs/openssl-3/include/internal/quic_demux.h b/libs/openssl-3/include/internal/quic_demux.h index 444249e72..d0781e61c 100644 --- a/libs/openssl-3/include/internal/quic_demux.h +++ b/libs/openssl-3/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 # 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); diff --git a/libs/openssl-3/include/internal/quic_engine.h b/libs/openssl-3/include/internal/quic_engine.h new file mode 100644 index 000000000..5d06d076b --- /dev/null +++ b/libs/openssl-3/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 + +# 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 diff --git a/libs/openssl-3/include/internal/quic_error.h b/libs/openssl-3/include/internal/quic_error.h index ae195a5f8..86d1c692b 100644 --- a/libs/openssl-3/include/internal/quic_error.h +++ b/libs/openssl-3/include/internal/quic_error.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 @@ -11,43 +11,18 @@ # define OSSL_QUIC_ERROR_H # include +# include # ifndef OPENSSL_NO_QUIC -/* RFC 9000 Section 20.1 */ -# define QUIC_ERR_NO_ERROR 0x00 -# define QUIC_ERR_INTERNAL_ERROR 0x01 -# define QUIC_ERR_CONNECTION_REFUSED 0x02 -# define QUIC_ERR_FLOW_CONTROL_ERROR 0x03 -# define QUIC_ERR_STREAM_LIMIT_ERROR 0x04 -# define QUIC_ERR_STREAM_STATE_ERROR 0x05 -# define QUIC_ERR_FINAL_SIZE_ERROR 0x06 -# define QUIC_ERR_FRAME_ENCODING_ERROR 0x07 -# define QUIC_ERR_TRANSPORT_PARAMETER_ERROR 0x08 -# define QUIC_ERR_CONNECTION_ID_LIMIT_ERROR 0x09 -# define QUIC_ERR_PROTOCOL_VIOLATION 0x0A -# define QUIC_ERR_INVALID_TOKEN 0x0B -# define QUIC_ERR_APPLICATION_ERROR 0x0C -# define QUIC_ERR_CRYPTO_BUFFER_EXCEEDED 0x0D -# define QUIC_ERR_KEY_UPDATE_ERROR 0x0E -# define QUIC_ERR_AEAD_LIMIT_REACHED 0x0F -# define QUIC_ERR_NO_VIABLE_PATH 0x10 - -/* Inclusive range for handshake-specific errors. */ -# define QUIC_ERR_CRYPTO_ERR_BEGIN 0x0100 -# define QUIC_ERR_CRYPTO_ERR_END 0x01FF - -# define QUIC_ERR_CRYPTO_ERR(X) \ - (QUIC_ERR_CRYPTO_ERR_BEGIN + (X)) - -# define QUIC_ERR_CRYPTO_UNEXPECTED_MESSAGE \ - QUIC_ERR_CRYPTO_ERR(SSL3_AD_UNEXPECTED_MESSAGE) - -# define QUIC_ERR_CRYPTO_MISSING_EXT \ - QUIC_ERR_CRYPTO_ERR(TLS13_AD_MISSING_EXTENSION) - -# define QUIC_ERR_CRYPTO_NO_APP_PROTO \ - QUIC_ERR_CRYPTO_ERR(TLS1_AD_NO_APPLICATION_PROTOCOL) +# define OSSL_QUIC_ERR_CRYPTO_UNEXPECTED_MESSAGE \ + OSSL_QUIC_ERR_CRYPTO_ERR(SSL3_AD_UNEXPECTED_MESSAGE) + +# define OSSL_QUIC_ERR_CRYPTO_MISSING_EXT \ + OSSL_QUIC_ERR_CRYPTO_ERR(TLS13_AD_MISSING_EXTENSION) + +# define OSSL_QUIC_ERR_CRYPTO_NO_APP_PROTO \ + OSSL_QUIC_ERR_CRYPTO_ERR(TLS1_AD_NO_APPLICATION_PROTOCOL) const char *ossl_quic_err_to_string(uint64_t error_code); diff --git a/libs/openssl-3/include/internal/quic_fc.h b/libs/openssl-3/include/internal/quic_fc.h index 49b448a3a..923bd43bc 100644 --- a/libs/openssl-3/include/internal/quic_fc.h +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/include/internal/quic_fifd.h b/libs/openssl-3/include/internal/quic_fifd.h index a260ec447..c1644e4d8 100644 --- a/libs/openssl-3/include/internal/quic_fifd.h +++ b/libs/openssl-3/include/internal/quic_fifd.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 @@ -16,6 +16,7 @@ # include "internal/quic_ackm.h" # include "internal/quic_txpim.h" # include "internal/quic_stream.h" +# include "internal/qlog.h" # ifndef OPENSSL_NO_QUIC @@ -45,6 +46,8 @@ struct quic_fifd_st { void (*sstream_updated)(uint64_t stream_id, void *arg); void *sstream_updated_arg; + QLOG *(*get_qlog_cb)(void *arg); + void *get_qlog_cb_arg; }; int ossl_quic_fifd_init(QUIC_FIFD *fifd, @@ -69,12 +72,17 @@ int ossl_quic_fifd_init(QUIC_FIFD *fifd, void *confirm_frame_arg, void (*sstream_updated)(uint64_t stream_id, void *arg), - void *sstream_updated_arg); + void *sstream_updated_arg, + QLOG *(*get_qlog_cb)(void *arg), + void *get_qlog_cb_arg); void ossl_quic_fifd_cleanup(QUIC_FIFD *fifd); /* (no-op) */ int ossl_quic_fifd_pkt_commit(QUIC_FIFD *fifd, QUIC_TXPIM_PKT *pkt); +void ossl_quic_fifd_set_qlog_cb(QUIC_FIFD *fifd, QLOG *(*get_qlog_cb)(void *arg), + void *arg); + # endif #endif diff --git a/libs/openssl-3/include/internal/quic_lcidm.h b/libs/openssl-3/include/internal/quic_lcidm.h new file mode 100644 index 000000000..4911e0423 --- /dev/null +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/include/internal/quic_port.h b/libs/openssl-3/include/internal/quic_port.h new file mode 100644 index 000000000..bcb578c3f --- /dev/null +++ b/libs/openssl-3/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 +# 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 diff --git a/libs/openssl-3/include/internal/quic_predef.h b/libs/openssl-3/include/internal/quic_predef.h new file mode 100644 index 000000000..7c7567b9c --- /dev/null +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/include/internal/quic_rcidm.h b/libs/openssl-3/include/internal/quic_rcidm.h new file mode 100644 index 000000000..fd102241b --- /dev/null +++ b/libs/openssl-3/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 diff --git a/libs/openssl-3/include/internal/quic_reactor.h b/libs/openssl-3/include/internal/quic_reactor.h index 54bfc1f6a..a6fdb7d12 100644 --- a/libs/openssl-3/include/internal/quic_reactor.h +++ b/libs/openssl-3/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 @@ -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, diff --git a/libs/openssl-3/include/internal/quic_record_rx.h b/libs/openssl-3/include/internal/quic_record_rx.h index e26fd3560..001509bd5 100644 --- a/libs/openssl-3/include/internal/quic_record_rx.h +++ b/libs/openssl-3/include/internal/quic_record_rx.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 @@ -13,6 +13,7 @@ # include # include "internal/quic_wire_pkt.h" # include "internal/quic_types.h" +# include "internal/quic_predef.h" # include "internal/quic_record_util.h" # include "internal/quic_demux.h" @@ -28,7 +29,7 @@ typedef struct ossl_qrx_args_st { OSSL_LIB_CTX *libctx; const char *propq; - /* Demux to receive datagrams from. */ + /* Demux which owns the URXEs passed to us. */ QUIC_DEMUX *demux; /* Length of connection IDs used in short-header packets in bytes. */ @@ -66,34 +67,6 @@ void ossl_qrx_set_msg_callback(OSSL_QRX *qrx, ossl_msg_cb msg_callback, void ossl_qrx_set_msg_callback_arg(OSSL_QRX *qrx, void *msg_callback_arg); -/* - * DCID Management - * =============== - */ - -/* - * Adds a given DCID to the QRX. The QRX will register the DCID with the demuxer - * so that incoming packets with that DCID are passed to the given QRX. Multiple - * DCIDs may be associated with a QRX at any one time. You will need to add at - * least one DCID after instantiating the QRX. A zero-length DCID is a valid - * input to this function. This function fails if the DCID is already - * registered. - * - * Returns 1 on success or 0 on error. - */ -int ossl_qrx_add_dst_conn_id(OSSL_QRX *qrx, - const QUIC_CONN_ID *dst_conn_id); - -/* - * Remove a DCID previously registered with ossl_qrx_add_dst_conn_id. The DCID - * is unregistered from the demuxer. Fails if the DCID is not registered with - * the demuxer. - * - * Returns 1 on success or 0 on error. - */ -int ossl_qrx_remove_dst_conn_id(OSSL_QRX *qrx, - const QUIC_CONN_ID *dst_conn_id); - /* * Secret Management * ================= @@ -206,7 +179,7 @@ int ossl_qrx_discard_enc_level(OSSL_QRX *qrx, uint32_t enc_level); */ /* Information about a received packet. */ -typedef struct ossl_qrx_pkt_st { +struct ossl_qrx_pkt_st { /* * Points to a logical representation of the decoded QUIC packet header. The * data and len fields point to the decrypted QUIC payload (i.e., to a @@ -252,7 +225,13 @@ typedef struct ossl_qrx_pkt_st { * packets. */ uint64_t key_epoch; -} OSSL_QRX_PKT; + + /* + * This monotonically increases with each datagram received. + * It is for diagnostic use only. + */ + uint64_t datagram_id; +}; /* * Tries to read a new decrypted packet from the QRX. diff --git a/libs/openssl-3/include/internal/quic_record_tx.h b/libs/openssl-3/include/internal/quic_record_tx.h index f3b798fea..e84523f89 100644 --- a/libs/openssl-3/include/internal/quic_record_tx.h +++ b/libs/openssl-3/include/internal/quic_record_tx.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 @@ -13,7 +13,9 @@ # include # include "internal/quic_wire_pkt.h" # include "internal/quic_types.h" +# include "internal/quic_predef.h" # include "internal/quic_record_util.h" +# include "internal/qlog.h" # ifndef OPENSSL_NO_QUIC @@ -46,6 +48,10 @@ typedef struct ossl_qtx_args_st { /* Maximum datagram payload length (MDPL) for TX purposes. */ size_t mdpl; + + /* Callback returning QLOG instance to use, or NULL. */ + QLOG *(*get_qlog_cb)(void *arg); + void *get_qlog_cb_arg; } OSSL_QTX_ARGS; /* Instantiates a new QTX. */ @@ -63,6 +69,10 @@ void ossl_qtx_set_msg_callback(OSSL_QTX *qtx, ossl_msg_cb msg_callback, SSL *msg_callback_ssl); void ossl_qtx_set_msg_callback_arg(OSSL_QTX *qtx, void *msg_callback_arg); +/* Change QLOG instance retrieval callback in use after instantiation. */ +void ossl_qtx_set_qlog_cb(OSSL_QTX *qtx, QLOG *(*get_qlog_cb)(void *arg), + void *get_qlog_cb_arg); + /* * Secret Management * ----------------- @@ -148,7 +158,7 @@ uint32_t ossl_qrl_get_suite_cipher_tag_len(uint32_t suite_id); * ------------------- */ -typedef struct ossl_qtx_pkt_st { +struct ossl_qtx_pkt_st { /* Logical packet header to be serialized. */ QUIC_PKT_HDR *hdr; @@ -176,7 +186,7 @@ typedef struct ossl_qtx_pkt_st { /* Packet flags. Zero or more OSSL_QTX_PKT_FLAG_* values. */ uint32_t flags; -} OSSL_QTX_PKT; +}; /* * More packets will be written which should be coalesced into a single diff --git a/libs/openssl-3/include/internal/quic_srt_gen.h b/libs/openssl-3/include/internal/quic_srt_gen.h new file mode 100644 index 000000000..a25e71aa8 --- /dev/null +++ b/libs/openssl-3/include/internal/quic_srt_gen.h @@ -0,0 +1,57 @@ +/* +* 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_SRT_GEN_H +# define OSSL_INTERNAL_QUIC_SRT_GEN_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 Stateless Reset Token Generator + * ==================================== + * + * This generates 16-byte QUIC Stateless Reset Tokens given a secret symmetric + * key and a DCID. Because the output is deterministic with regards to these + * inputs, assuming the same key is used between invocations of a process, we + * are able to generate the same stateless reset token in a subsequent process, + * thereby allowing us to achieve stateless reset of a peer which still thinks + * it is connected to a past process at the same UDP address. + */ +typedef struct quic_srt_gen_st QUIC_SRT_GEN; + +/* + * Create a new stateless reset token generator using the given key as input. + * The key may be of arbitrary length. + * + * The caller is responsible for performing domain separation with regards to + * the key; i.e., the caller is responsible for ensuring the key is never used + * in any other context. + */ +QUIC_SRT_GEN *ossl_quic_srt_gen_new(OSSL_LIB_CTX *libctx, const char *propq, + const unsigned char *key, size_t key_len); + +/* Free the stateless reset token generator. No-op if srt_gen is NULL. */ +void ossl_quic_srt_gen_free(QUIC_SRT_GEN *srt_gen); + +/* + * Calculates a token using the given DCID and writes it to *token. Returns 0 on + * failure. + */ +int ossl_quic_srt_gen_calculate_token(QUIC_SRT_GEN *srt_gen, + const QUIC_CONN_ID *dcid, + QUIC_STATELESS_RESET_TOKEN *token); + +# endif +#endif diff --git a/libs/openssl-3/include/internal/quic_srtm.h b/libs/openssl-3/include/internal/quic_srtm.h new file mode 100644 index 000000000..d60c285e2 --- /dev/null +++ b/libs/openssl-3/include/internal/quic_srtm.h @@ -0,0 +1,109 @@ +/* +* 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_SRTM_H +# define OSSL_INTERNAL_QUIC_SRTM_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 Stateless Reset Token Manager + * ================================== + * + * The stateless reset token manager is responsible for mapping stateless reset + * tokens to connections. It is used to identify stateless reset tokens in + * incoming packets. In this regard it can be considered an alternate "routing" + * mechanism for incoming packets, and is somewhat analogous with the LCIDM, + * except that it uses SRTs to route rather than DCIDs. + * + * The SRTM specifically stores a bidirectional mapping of the form + * + * (opaque pointer, sequence number) [1] <-> [0..n] SRT + * + * The (opaque pointer, sequence number) tuple is used to refer to an entry (for + * example for the purposes of removing it later when it is no longer needed). + * Likewise, an entry can be looked up using SRT to get the opaque pointer and + * sequence number. + * + * It is important to note that the same SRT may exist multiple times and map to + * multiple (opaque pointer, sequence number) tuples, for example, if we + * initiate multiple connections to the same peer using the same local QUIC_PORT + * and the peer decides to behave bizarrely and issue the same SRT for both + * connections. It should not do this, but we have to be resilient against + * byzantine peer behaviour. Thus we are capable of storing multiple identical + * SRTs for different (opaque pointer, sequence number) keys. + * + * The SRTM supports arbitrary insertion, arbitrary deletion of specific keys + * identified by a (opaque pointer, sequence number) key, and mass deletion of + * all entries under a specific opaque pointer. It supports lookup by SRT to + * identify zero or more corresponding (opaque pointer, sequence number) tuples. + * + * The opaque pointer may be used for any purpose but is intended to represent a + * connection identity and must therefore be consistent (usefully comparable). + */ + +/* Creates a new empty SRTM instance. */ +QUIC_SRTM *ossl_quic_srtm_new(OSSL_LIB_CTX *libctx, const char *propq); + +/* Frees a SRTM instance. No-op if srtm is NULL. */ +void ossl_quic_srtm_free(QUIC_SRTM *srtm); + +/* + * Add a (opaque, seq_num) -> SRT entry to the SRTM. This operation fails if a + * SRT entry already exists with the same (opaque, seq_num) tuple. The token is + * copied. Returns 1 on success or 0 on failure. + */ +int ossl_quic_srtm_add(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num, + const QUIC_STATELESS_RESET_TOKEN *token); + +/* + * Removes an entry by identifying it via its (opaque, seq_num) tuple. + * Returns 1 if the entry was found and removed, and 0 if it was not found. + */ +int ossl_quic_srtm_remove(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num); + +/* + * Removes all entries (opaque, *) with the given opaque pointer. + * + * Returns 1 on success and 0 on failure. If no entries with the given opaque + * pointer were found, this is considered a success condition. + */ +int ossl_quic_srtm_cull(QUIC_SRTM *strm, void *opaque); + +/* + * Looks up a SRT to find the corresponding opaque pointer and sequence number. + * An output field pointer can be set to NULL if it is not required. + * + * This function is designed to avoid exposing timing channels on token values + * or the contents of the SRT mapping. + * + * If there are several identical SRTs, idx can be used to get the nth entry. + * Call this function with idx set to 0 first, and keep calling it after + * incrementing idx until it returns 0. + * + * Returns 1 if an entry was found and 0 otherwise. + */ +int ossl_quic_srtm_lookup(QUIC_SRTM *srtm, + const QUIC_STATELESS_RESET_TOKEN *token, + size_t idx, + void **opaque, uint64_t *seq_num); + +/* Verify internal invariants and assert if they are not met. */ +void ossl_quic_srtm_check(const QUIC_SRTM *srtm); + +# endif + +#endif diff --git a/libs/openssl-3/include/internal/quic_ssl.h b/libs/openssl-3/include/internal/quic_ssl.h index 52d4527c8..4fc7a21a5 100644 --- a/libs/openssl-3/include/internal/quic_ssl.h +++ b/libs/openssl-3/include/internal/quic_ssl.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 @@ -28,6 +28,8 @@ __owur int ossl_quic_accept(SSL *s); __owur int ossl_quic_connect(SSL *s); __owur int ossl_quic_read(SSL *s, void *buf, size_t len, size_t *readbytes); __owur int ossl_quic_peek(SSL *s, void *buf, size_t len, size_t *readbytes); +__owur int ossl_quic_write_flags(SSL *s, const void *buf, size_t len, + uint64_t flags, size_t *written); __owur int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written); __owur long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg); __owur long ossl_quic_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); @@ -83,6 +85,10 @@ __owur int ossl_quic_set_incoming_stream_policy(SSL *s, int policy, uint64_t aec); __owur SSL *ossl_quic_accept_stream(SSL *s, uint64_t flags); __owur size_t ossl_quic_get_accept_stream_queue_len(SSL *s); +__owur int ossl_quic_get_value_uint(SSL *s, uint32_t class_, uint32_t id, + uint64_t *value); +__owur int ossl_quic_set_value_uint(SSL *s, uint32_t class_, uint32_t id, + uint64_t value); __owur int ossl_quic_stream_reset(SSL *ssl, const SSL_STREAM_RESET_ARGS *args, @@ -127,6 +133,19 @@ QUIC_CHANNEL *ossl_quic_conn_get_channel(SSL *s); int ossl_quic_has_pending(const SSL *s); int ossl_quic_get_shutdown(const SSL *s); +/* + * Set qlog diagnostic title. String is copied internally on success and need + * not remain allocated. Only has any effect if logging has not already begun. + * For use by tests only. Setting this on a context affects any QCSO created + * after this is called but does not affect QCSOs already created from a + * context. + */ +int ossl_quic_set_diag_title(SSL_CTX *ctx, const char *title); + +/* APIs used by the polling infrastructure */ +int ossl_quic_conn_poll_events(SSL *ssl, uint64_t events, int do_tick, + uint64_t *revents); + # endif #endif diff --git a/libs/openssl-3/include/internal/quic_statm.h b/libs/openssl-3/include/internal/quic_statm.h index 5b33551b0..2fca69b0d 100644 --- a/libs/openssl-3/include/internal/quic_statm.h +++ b/libs/openssl-3/include/internal/quic_statm.h @@ -12,13 +12,14 @@ # include # include "internal/time.h" +# include "internal/quic_predef.h" # ifndef OPENSSL_NO_QUIC -typedef struct ossl_statm_st { +struct ossl_statm_st { OSSL_TIME smoothed_rtt, latest_rtt, min_rtt, rtt_variance; char have_first_sample; -} OSSL_STATM; +}; typedef struct ossl_rtt_info_st { /* As defined in RFC 9002. */ diff --git a/libs/openssl-3/include/internal/quic_stream.h b/libs/openssl-3/include/internal/quic_stream.h index 0da8febd5..d446dadc5 100644 --- a/libs/openssl-3/include/internal/quic_stream.h +++ b/libs/openssl-3/include/internal/quic_stream.h @@ -14,6 +14,7 @@ #include "internal/e_os.h" #include "internal/time.h" #include "internal/quic_types.h" +#include "internal/quic_predef.h" #include "internal/quic_wire.h" #include "internal/quic_record_tx.h" #include "internal/quic_record_rx.h" @@ -51,7 +52,6 @@ * datagrams. The terms 'send' and 'receive' are used when referring to the * stream abstraction. Applications send; we transmit. */ -typedef struct quic_sstream_st QUIC_SSTREAM; /* * Instantiates a new QUIC_SSTREAM. init_buf_size specifies the initial size of @@ -312,7 +312,6 @@ void ossl_quic_sstream_set_cleanse(QUIC_SSTREAM *qss, int cleanse); * (i.e., for a unidirectional receiving stream or for the receiving component * of a bidirectional stream). */ -typedef struct quic_rstream_st QUIC_RSTREAM; /* * Create a new instance of QUIC_RSTREAM with pointers to the flow diff --git a/libs/openssl-3/include/internal/quic_stream_map.h b/libs/openssl-3/include/internal/quic_stream_map.h index 26fc58040..745d9c03d 100644 --- a/libs/openssl-3/include/internal/quic_stream_map.h +++ b/libs/openssl-3/include/internal/quic_stream_map.h @@ -15,6 +15,7 @@ # include "internal/time.h" # include "internal/common.h" # include "internal/quic_types.h" +# include "internal/quic_predef.h" # include "internal/quic_stream.h" # include "internal/quic_fc.h" # include @@ -27,7 +28,6 @@ * * Logical QUIC stream composing all relevant send and receive components. */ -typedef struct quic_stream_st QUIC_STREAM; typedef struct quic_stream_list_node_st QUIC_STREAM_LIST_NODE; @@ -549,20 +549,20 @@ static ossl_inline ossl_unused int ossl_quic_stream_recv_pending(const QUIC_STRE * - allows iteration over the active streams only. * */ -typedef struct quic_stream_map_st { +struct quic_stream_map_st { LHASH_OF(QUIC_STREAM) *map; QUIC_STREAM_LIST_NODE active_list; QUIC_STREAM_LIST_NODE accept_list; QUIC_STREAM_LIST_NODE ready_for_gc_list; size_t rr_stepping, rr_counter; - size_t num_accept, num_shutdown_flush; + size_t num_accept_bidi, num_accept_uni, num_shutdown_flush; QUIC_STREAM *rr_cur; uint64_t (*get_stream_limit_cb)(int uni, void *arg); void *get_stream_limit_cb_arg; QUIC_RXFC *max_streams_bidi_rxfc; QUIC_RXFC *max_streams_uni_rxfc; int is_server; -} QUIC_STREAM_MAP; +}; /* * get_stream_limit is a callback which is called to retrieve the current stream @@ -841,8 +841,11 @@ void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s, OSSL_TIME rtt); -/* Returns the length of the accept queue. */ -size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm); +/* Returns the length of the accept queue for the given stream type. */ +size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm, int is_uni); + +/* Returns the total length of the accept queues for all stream types. */ +size_t ossl_quic_stream_map_get_total_accept_queue_len(QUIC_STREAM_MAP *qsm); /* * Shutdown Flush and GC diff --git a/libs/openssl-3/include/internal/quic_tls.h b/libs/openssl-3/include/internal/quic_tls.h index 0e4a9d339..f9f007a76 100644 --- a/libs/openssl-3/include/internal/quic_tls.h +++ b/libs/openssl-3/include/internal/quic_tls.h @@ -12,9 +12,9 @@ # include # include "internal/quic_stream.h" +# include "internal/quic_predef.h" - -typedef struct quic_tls_st QUIC_TLS; +# ifndef OPENSSL_NO_QUIC typedef struct quic_tls_args_st { /* @@ -103,4 +103,6 @@ int ossl_quic_tls_get_error(QUIC_TLS *qtls, int ossl_quic_tls_is_cert_request(QUIC_TLS *qtls); int ossl_quic_tls_has_bad_max_early_data(QUIC_TLS *qtls); +# endif + #endif diff --git a/libs/openssl-3/include/internal/quic_txp.h b/libs/openssl-3/include/internal/quic_txp.h index ae508f239..607cefc01 100644 --- a/libs/openssl-3/include/internal/quic_txp.h +++ b/libs/openssl-3/include/internal/quic_txp.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 # include "internal/quic_types.h" +# include "internal/quic_predef.h" # include "internal/quic_record_tx.h" # include "internal/quic_cfq.h" # include "internal/quic_txpim.h" @@ -20,6 +21,7 @@ # include "internal/quic_fc.h" # include "internal/bio_addr.h" # include "internal/time.h" +# include "internal/qlog.h" # ifndef OPENSSL_NO_QUIC @@ -48,6 +50,8 @@ typedef struct ossl_quic_tx_packetiser_args_st { OSSL_CC_DATA *cc_data; /* QUIC Congestion Controller Instance */ OSSL_TIME (*now)(void *arg); /* Callback to get current time. */ void *now_arg; + QLOG *(*get_qlog_cb)(void *arg); /* Optional QLOG retrieval func */ + void *get_qlog_cb_arg; /* * Injected dependencies - crypto streams. @@ -59,8 +63,6 @@ typedef struct ossl_quic_tx_packetiser_args_st { } OSSL_QUIC_TX_PACKETISER_ARGS; -typedef struct ossl_quic_tx_packetiser_st OSSL_QUIC_TX_PACKETISER; - OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETISER_ARGS *args); typedef void (ossl_quic_initial_token_free_fn)(const unsigned char *buf, @@ -137,6 +139,13 @@ int ossl_quic_tx_packetiser_set_cur_scid(OSSL_QUIC_TX_PACKETISER *txp, int ossl_quic_tx_packetiser_set_peer(OSSL_QUIC_TX_PACKETISER *txp, const BIO_ADDR *peer); +/* + * Change the QLOG instance retrieval function in use after instantiation. + */ +void ossl_quic_tx_packetiser_set_qlog_cb(OSSL_QUIC_TX_PACKETISER *txp, + QLOG *(*get_qlog_cb)(void *arg), + void *get_qlog_cb_arg); + /* * Inform the TX packetiser that an EL has been discarded. Idempotent. * diff --git a/libs/openssl-3/include/internal/quic_txpim.h b/libs/openssl-3/include/internal/quic_txpim.h index ed6e3875c..5df6ad46c 100644 --- a/libs/openssl-3/include/internal/quic_txpim.h +++ b/libs/openssl-3/include/internal/quic_txpim.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 # include "internal/quic_types.h" +# include "internal/quic_predef.h" # include "internal/quic_cfq.h" # include "internal/quic_ackm.h" @@ -21,8 +22,6 @@ * QUIC Transmitted Packet Information Manager * =========================================== */ -typedef struct quic_txpim_st QUIC_TXPIM; -typedef struct quic_fifd_st QUIC_FIFD; typedef struct quic_txpim_pkt_st { /* ACKM-specific data. Caller should fill this. */ @@ -34,6 +33,9 @@ typedef struct quic_txpim_pkt_st { /* Reserved for FIFD use. */ QUIC_FIFD *fifd; + /* QUIC_PKT_TYPE value. For diagnostic use only. */ + unsigned char pkt_type; + /* Regenerate-strategy frames. */ unsigned int had_handshake_done_frame : 1; unsigned int had_max_data_frame : 1; diff --git a/libs/openssl-3/include/internal/quic_types.h b/libs/openssl-3/include/internal/quic_types.h index d42164ba5..fa1ac81ca 100644 --- a/libs/openssl-3/include/internal/quic_types.h +++ b/libs/openssl-3/include/internal/quic_types.h @@ -73,6 +73,7 @@ static ossl_unused ossl_inline int ossl_quic_pn_valid(QUIC_PN pn) /* QUIC connection ID representation. */ # define QUIC_MAX_CONN_ID_LEN 20 +# define QUIC_MIN_ODCID_LEN 8 /* RFC 9000 s. 7.2 */ typedef struct quic_conn_id_st { unsigned char id_len, id[QUIC_MAX_CONN_ID_LEN]; @@ -86,6 +87,13 @@ static ossl_unused ossl_inline int ossl_quic_conn_id_eq(const QUIC_CONN_ID *a, return memcmp(a->id, b->id, a->id_len) == 0; } +/* + * Generates a random CID of the given length. libctx may be NULL. + * Returns 1 on success or 0 on failure. + */ +int ossl_quic_gen_rand_conn_id(OSSL_LIB_CTX *libctx, size_t len, + QUIC_CONN_ID *cid); + # define QUIC_MIN_INITIAL_DGRAM_LEN 1200 # define QUIC_DEFAULT_ACK_DELAY_EXP 3 diff --git a/libs/openssl-3/include/internal/rcu.h b/libs/openssl-3/include/internal/rcu.h new file mode 100644 index 000000000..7716a1c7f --- /dev/null +++ b/libs/openssl-3/include/internal/rcu.h @@ -0,0 +1,31 @@ +/* + * 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 OPENSSL_RCU_H +# define OPENSSL_RCU_H +# pragma once + +typedef void (*rcu_cb_fn)(void *data); + +typedef struct rcu_lock_st CRYPTO_RCU_LOCK; + +CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers); +void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock); +void ossl_rcu_read_lock(CRYPTO_RCU_LOCK *lock); +void ossl_rcu_write_lock(CRYPTO_RCU_LOCK *lock); +void ossl_rcu_write_unlock(CRYPTO_RCU_LOCK *lock); +void ossl_rcu_read_unlock(CRYPTO_RCU_LOCK *lock); +void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock); +int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data); +void *ossl_rcu_uptr_deref(void **p); +void ossl_rcu_assign_uptr(void **p, void **v); +#define ossl_rcu_deref(p) ossl_rcu_uptr_deref((void **)p) +#define ossl_rcu_assign_ptr(p,v) ossl_rcu_assign_uptr((void **)p, (void **)v) + +#endif diff --git a/libs/openssl-3/include/internal/sha3.h b/libs/openssl-3/include/internal/sha3.h index 80ad86e58..332916aa5 100644 --- a/libs/openssl-3/include/internal/sha3.h +++ b/libs/openssl-3/include/internal/sha3.h @@ -22,23 +22,31 @@ typedef struct keccak_st KECCAK1600_CTX; -typedef size_t (sha3_absorb_fn)(void *vctx, const void *inp, size_t len); -typedef int (sha3_final_fn)(unsigned char *md, void *vctx); +typedef size_t (sha3_absorb_fn)(void *vctx, const void *in, size_t inlen); +typedef int (sha3_final_fn)(void *vctx, unsigned char *out, size_t outlen); +typedef int (sha3_squeeze_fn)(void *vctx, unsigned char *out, size_t outlen); typedef struct prov_sha3_meth_st { sha3_absorb_fn *absorb; sha3_final_fn *final; + sha3_squeeze_fn *squeeze; } PROV_SHA3_METHOD; +#define XOF_STATE_INIT 0 +#define XOF_STATE_ABSORB 1 +#define XOF_STATE_FINAL 2 +#define XOF_STATE_SQUEEZE 3 + struct keccak_st { uint64_t A[5][5]; + unsigned char buf[KECCAK1600_WIDTH / 8 - 32]; size_t block_size; /* cached ctx->digest->block_size */ size_t md_size; /* output length, variable in XOF */ size_t bufsz; /* used bytes in below buffer */ - unsigned char buf[KECCAK1600_WIDTH / 8 - 32]; unsigned char pad; PROV_SHA3_METHOD meth; + int xof_state; }; void ossl_sha3_reset(KECCAK1600_CTX *ctx); @@ -46,7 +54,8 @@ int ossl_sha3_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen); int ossl_keccak_kmac_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen); int ossl_sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len); -int ossl_sha3_final(unsigned char *md, KECCAK1600_CTX *ctx); +int ossl_sha3_final(KECCAK1600_CTX *ctx, unsigned char *out, size_t outlen); +int ossl_sha3_squeeze(KECCAK1600_CTX *ctx, unsigned char *out, size_t outlen); size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len, size_t r); diff --git a/libs/openssl-3/include/internal/sockets.h b/libs/openssl-3/include/internal/sockets.h index 2550c56bd..f51c1b075 100644 --- a/libs/openssl-3/include/internal/sockets.h +++ b/libs/openssl-3/include/internal/sockets.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 @@ -190,14 +190,8 @@ typedef size_t socklen_t; /* Currently appears to be missing on VMS */ # define readsocket(s,b,n) read((s),(b),(n)) # define writesocket(s,b,n) write((s),(char *)(b),(n)) # elif defined(OPENSSL_SYS_TANDEM) -# if defined(OPENSSL_TANDEM_FLOSS) -# include -# define readsocket(s,b,n) floss_read((s),(b),(n)) -# define writesocket(s,b,n) floss_write((s),(b),(n)) -# else -# define readsocket(s,b,n) read((s),(b),(n)) -# define writesocket(s,b,n) write((s),(b),(n)) -# endif +# define readsocket(s,b,n) read((s),(b),(n)) +# define writesocket(s,b,n) write((s),(b),(n)) # define ioctlsocket(a,b,c) ioctl(a,b,c) # define closesocket(s) close(s) # else diff --git a/libs/openssl-3/include/openssl/asn1err.h b/libs/openssl-3/include/openssl/asn1err.h index d4276220c..8fd85ed88 100644 --- a/libs/openssl-3/include/openssl/asn1err.h +++ b/libs/openssl-3/include/openssl/asn1err.h @@ -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 @@ -47,6 +47,7 @@ # define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 # define ASN1_R_FIELD_MISSING 121 # define ASN1_R_FIRST_NUM_TOO_LARGE 122 +# define ASN1_R_GENERALIZEDTIME_IS_TOO_SHORT 232 # define ASN1_R_HEADER_TOO_LONG 123 # define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 # define ASN1_R_ILLEGAL_BOOLEAN 176 @@ -133,6 +134,7 @@ # define ASN1_R_UNSUPPORTED_CIPHER 228 # define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 # define ASN1_R_UNSUPPORTED_TYPE 196 +# define ASN1_R_UTCTIME_IS_TOO_SHORT 233 # define ASN1_R_WRONG_INTEGER_TYPE 225 # define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 # define ASN1_R_WRONG_TAG 168 diff --git a/libs/openssl-3/include/openssl/bio.h b/libs/openssl-3/include/openssl/bio.h index f0b98af44..040debac6 100644 --- a/libs/openssl-3/include/openssl/bio.h +++ b/libs/openssl-3/include/openssl/bio.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by makefile from include\openssl\bio.h.in * - * 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 @@ -70,7 +70,10 @@ extern "C" { # define BIO_TYPE_DGRAM_PAIR (26|BIO_TYPE_SOURCE_SINK) # define BIO_TYPE_DGRAM_MEM (27|BIO_TYPE_SOURCE_SINK) +/* Custom type starting index returned by BIO_get_new_index() */ #define BIO_TYPE_START 128 +/* Custom type maximum index that can be returned by BIO_get_new_index() */ +#define BIO_TYPE_MASK 0xFF /* * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. @@ -407,6 +410,7 @@ typedef struct bio_mmsg_cb_args_st { #define BIO_POLL_DESCRIPTOR_TYPE_NONE 0 #define BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD 1 +#define BIO_POLL_DESCRIPTOR_TYPE_SSL 2 #define BIO_POLL_DESCRIPTOR_CUSTOM_START 8192 typedef struct bio_poll_descriptor_st { @@ -415,6 +419,7 @@ typedef struct bio_poll_descriptor_st { int fd; void *custom; uintptr_t custom_ui; + SSL *ssl; } value; } BIO_POLL_DESCRIPTOR; diff --git a/libs/openssl-3/include/openssl/cmp.h b/libs/openssl-3/include/openssl/cmp.h index 3a1c52d18..2496e7158 100644 --- a/libs/openssl-3/include/openssl/cmp.h +++ b/libs/openssl-3/include/openssl/cmp.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by makefile from include\openssl\cmp.h.in * - * 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 * @@ -380,6 +380,10 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, OSSL_CMP_ITAV *itav); void OSSL_CMP_ITAV_free(OSSL_CMP_ITAV *itav); +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new0_certProfile(STACK_OF(ASN1_UTF8STRING) + *certProfile); +int OSSL_CMP_ITAV_get0_certProfile(const OSSL_CMP_ITAV *itav, + STACK_OF(ASN1_UTF8STRING) **out); OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts); int OSSL_CMP_ITAV_get0_caCerts(const OSSL_CMP_ITAV *itav, STACK_OF(X509) **out); @@ -425,6 +429,7 @@ const char *OSSL_CMP_CTX_get0_propq(const OSSL_CMP_CTX *ctx); # define OSSL_CMP_OPT_DIGEST_ALGNID 34 # define OSSL_CMP_OPT_IGNORE_KEYUSAGE 35 # define OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR 36 +# define OSSL_CMP_OPT_NO_CACHE_EXTRACERTS 37 int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val); int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt); /* CMP-specific callback for logging and outputting the error queue: */ @@ -470,6 +475,8 @@ int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, int OSSL_CMP_CTX_set1_recipient(OSSL_CMP_CTX *ctx, const X509_NAME *name); int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav); int OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx); +STACK_OF(OSSL_CMP_ITAV) + *OSSL_CMP_CTX_get0_geninfo_ITAVs(const OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx, STACK_OF(X509) *extraCertsOut); /* certificate template: */ @@ -522,10 +529,13 @@ OSSL_CMP_STATUSINFO_new(int status, int fail_info, const char *text); ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const OSSL_CMP_PKIHEADER *hdr); ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr); +STACK_OF(OSSL_CMP_ITAV) + *OSSL_CMP_HDR_get0_geninfo_ITAVs(const OSSL_CMP_PKIHEADER *hdr); /* from cmp_msg.c */ OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg); int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG *msg); +X509_PUBKEY *OSSL_CMP_MSG_get0_certreq_publickey(const OSSL_CMP_MSG *msg); int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); int OSSL_CMP_MSG_update_recipNonce(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid); @@ -587,6 +597,13 @@ int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx, OSSL_CMP_SRV_error_cb_t process_error, OSSL_CMP_SRV_certConf_cb_t process_certConf, OSSL_CMP_SRV_pollReq_cb_t process_pollReq); +typedef int (*OSSL_CMP_SRV_delayed_delivery_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req); +typedef int (*OSSL_CMP_SRV_clean_transaction_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx, + const ASN1_OCTET_STRING *id); +int OSSL_CMP_SRV_CTX_init_trans(OSSL_CMP_SRV_CTX *srv_ctx, + OSSL_CMP_SRV_delayed_delivery_cb_t delay, + OSSL_CMP_SRV_clean_transaction_cb_t clean); OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx); void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx); int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx, @@ -603,6 +620,8 @@ X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type, # define OSSL_CMP_CR 2 # define OSSL_CMP_P10CR 4 # define OSSL_CMP_KUR 7 +# define OSSL_CMP_GENM 21 +# define OSSL_CMP_ERROR 23 # define OSSL_CMP_exec_IR_ses(ctx) \ OSSL_CMP_exec_certreq(ctx, OSSL_CMP_IR, NULL) # define OSSL_CMP_exec_CR_ses(ctx) \ diff --git a/libs/openssl-3/include/openssl/cmperr.h b/libs/openssl-3/include/openssl/cmperr.h index 57a6effbe..0d876e501 100644 --- a/libs/openssl-3/include/openssl/cmperr.h +++ b/libs/openssl-3/include/openssl/cmperr.h @@ -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 @@ -55,6 +55,7 @@ # define CMP_R_ERROR_UNEXPECTED_CERTCONF 160 # define CMP_R_ERROR_VALIDATING_PROTECTION 140 # define CMP_R_ERROR_VALIDATING_SIGNATURE 171 +# define CMP_R_EXPECTED_POLLREQ 104 # define CMP_R_FAILED_BUILDING_OWN_CHAIN 164 # define CMP_R_FAILED_EXTRACTING_PUBKEY 141 # define CMP_R_FAILURE_OBTAINING_RANDOM 110 @@ -98,14 +99,18 @@ # define CMP_R_TRANSACTIONID_UNMATCHED 152 # define CMP_R_TRANSFER_ERROR 159 # define CMP_R_UNCLEAN_CTX 191 +# define CMP_R_UNEXPECTED_CERTPROFILE 196 # define CMP_R_UNEXPECTED_PKIBODY 133 # define CMP_R_UNEXPECTED_PKISTATUS 185 +# define CMP_R_UNEXPECTED_POLLREQ 105 # define CMP_R_UNEXPECTED_PVNO 153 +# define CMP_R_UNEXPECTED_SENDER 106 # define CMP_R_UNKNOWN_ALGORITHM_ID 134 # define CMP_R_UNKNOWN_CERT_TYPE 135 # define CMP_R_UNKNOWN_PKISTATUS 186 # define CMP_R_UNSUPPORTED_ALGORITHM 136 # define CMP_R_UNSUPPORTED_KEY_TYPE 137 +# define CMP_R_UNSUPPORTED_PKIBODY 101 # define CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC 154 # define CMP_R_VALUE_TOO_LARGE 175 # define CMP_R_VALUE_TOO_SMALL 177 diff --git a/libs/openssl-3/include/openssl/conf.h b/libs/openssl-3/include/openssl/conf.h index f61918ca0..367a16eaa 100644 --- a/libs/openssl-3/include/openssl/conf.h +++ b/libs/openssl-3/include/openssl/conf.h @@ -68,7 +68,7 @@ SKM_DEFINE_STACK_OF_INTERNAL(CONF_VALUE, CONF_VALUE, CONF_VALUE) #define sk_CONF_VALUE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(CONF_VALUE) *)OPENSSL_sk_deep_copy(ossl_check_const_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_copyfunc_type(copyfunc), ossl_check_CONF_VALUE_freefunc_type(freefunc))) #define sk_CONF_VALUE_set_cmp_func(sk, cmp) ((sk_CONF_VALUE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_compfunc_type(cmp))) DEFINE_LHASH_OF_INTERNAL(CONF_VALUE); -#define lh_CONF_VALUE_new(hfn, cmp) ((LHASH_OF(CONF_VALUE) *)OPENSSL_LH_new(ossl_check_CONF_VALUE_lh_hashfunc_type(hfn), ossl_check_CONF_VALUE_lh_compfunc_type(cmp))) +#define lh_CONF_VALUE_new(hfn, cmp) ((LHASH_OF(CONF_VALUE) *)OPENSSL_LH_set_thunks(OPENSSL_LH_new(ossl_check_CONF_VALUE_lh_hashfunc_type(hfn), ossl_check_CONF_VALUE_lh_compfunc_type(cmp)), lh_CONF_VALUE_hash_thunk, lh_CONF_VALUE_comp_thunk, lh_CONF_VALUE_doall_thunk, lh_CONF_VALUE_doall_arg_thunk)) #define lh_CONF_VALUE_free(lh) OPENSSL_LH_free(ossl_check_CONF_VALUE_lh_type(lh)) #define lh_CONF_VALUE_flush(lh) OPENSSL_LH_flush(ossl_check_CONF_VALUE_lh_type(lh)) #define lh_CONF_VALUE_insert(lh, ptr) ((CONF_VALUE *)OPENSSL_LH_insert(ossl_check_CONF_VALUE_lh_type(lh), ossl_check_CONF_VALUE_lh_plain_type(ptr))) diff --git a/libs/openssl-3/include/openssl/configuration.h b/libs/openssl-3/include/openssl/configuration.h index ebe4226d9..fa2acf2d5 100644 --- a/libs/openssl-3/include/openssl/configuration.h +++ b/libs/openssl-3/include/openssl/configuration.h @@ -1,159 +1,258 @@ -/* - * WARNING: do not edit! - * Generated by configdata.pm from Configurations\common0.tmpl, Configurations\windows-makefile.tmpl - * via makefile.in - * - * Copyright 2016-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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_CONFIGURATION_H -# define OPENSSL_CONFIGURATION_H -# pragma once - -# ifdef __cplusplus -extern "C" { -# endif - -# ifdef OPENSSL_ALGORITHM_DEFINES -# error OPENSSL_ALGORITHM_DEFINES no longer supported -# endif - -/* - * OpenSSL was configured with the following options: - */ - -# ifndef OPENSSL_SYS_WIN32 -# define OPENSSL_SYS_WIN32 1 -# endif -# define OPENSSL_CONFIGURED_API 30100 -# ifndef OPENSSL_RAND_SEED_OS -# define OPENSSL_RAND_SEED_OS -# endif -# ifndef OPENSSL_THREADS -# define OPENSSL_THREADS -# endif -# ifndef OPENSSL_NO_ACVP_TESTS -# define OPENSSL_NO_ACVP_TESTS -# endif -# ifndef OPENSSL_NO_AFALGENG -# define OPENSSL_NO_AFALGENG -# endif -# ifndef OPENSSL_NO_ASAN -# define OPENSSL_NO_ASAN -# endif -# ifndef OPENSSL_NO_CRYPTO_MDEBUG -# define OPENSSL_NO_CRYPTO_MDEBUG -# endif -# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE -# define OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE -# endif -# ifndef OPENSSL_NO_DEVCRYPTOENG -# define OPENSSL_NO_DEVCRYPTOENG -# endif - -#define OPENSSL_SYS_WINDOWS -#define OPENSSL_NO_TS - -# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 -# define OPENSSL_NO_EC_NISTP_64_GCC_128 -# endif -# ifndef OPENSSL_NO_EGD -# define OPENSSL_NO_EGD -# endif -# ifndef OPENSSL_NO_EXTERNAL_TESTS -# define OPENSSL_NO_EXTERNAL_TESTS -# endif -# ifndef OPENSSL_NO_FIPS_SECURITYCHECKS -# define OPENSSL_NO_FIPS_SECURITYCHECKS -# endif -# ifndef OPENSSL_NO_FUZZ_AFL -# define OPENSSL_NO_FUZZ_AFL -# endif -# ifndef OPENSSL_NO_FUZZ_LIBFUZZER -# define OPENSSL_NO_FUZZ_LIBFUZZER -# endif -# ifndef OPENSSL_NO_KTLS -# define OPENSSL_NO_KTLS -# endif -# ifndef OPENSSL_NO_MD2 -# define OPENSSL_NO_MD2 -# endif -# ifndef OPENSSL_NO_MSAN -# define OPENSSL_NO_MSAN -# endif -# ifndef OPENSSL_NO_RC5 -# define OPENSSL_NO_RC5 -# endif -# ifndef OPENSSL_NO_RFC3779 -# define OPENSSL_NO_RFC3779 -# endif -# ifndef OPENSSL_NO_SCTP -# define OPENSSL_NO_SCTP -# endif -# ifndef OPENSSL_NO_SSL_TRACE -# define OPENSSL_NO_SSL_TRACE -# endif -# ifndef OPENSSL_NO_SSL3 -# define OPENSSL_NO_SSL3 -# endif -# ifndef OPENSSL_NO_SSL3_METHOD -# define OPENSSL_NO_SSL3_METHOD -# endif -# ifndef OPENSSL_NO_TRACE -# define OPENSSL_NO_TRACE -# endif -# ifndef OPENSSL_NO_UBSAN -# define OPENSSL_NO_UBSAN -# endif -# ifndef OPENSSL_NO_UNIT_TEST -# define OPENSSL_NO_UNIT_TEST -# endif -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS -# define OPENSSL_NO_WEAK_SSL_CIPHERS -# endif -# ifndef OPENSSL_NO_STATIC_ENGINE -# define OPENSSL_NO_STATIC_ENGINE -# endif - - -/* Generate 80386 code? */ -# undef I386_ONLY - -#define ENGINESDIR "C:\\Program Files (x86)\\OpenSSL\\lib\\engines-3" -#define MODULESDIR "C:\\Program Files (x86)\\OpenSSL\\lib\\ossl-modules" -#define OPENSSLDIR "C:\\Program Files (x86)\\Common Files\\SSL" - -/* - * The following are cipher-specific, but are part of the public API. - */ -# if !defined(OPENSSL_SYS_UEFI) -# define BN_LLONG -/* Only one for the following should be defined */ -# undef SIXTY_FOUR_BIT_LONG -# undef SIXTY_FOUR_BIT -# define THIRTY_TWO_BIT -#endif - -# define RC4_INT unsigned int - -#define _setmode setmode -#define _strdup strdup - -# ifdef __cplusplus -} -# endif - -#ifndef _timeb -#define _timeb timeb -#endif - -#ifndef _ftime -#define _ftime ftime -#endif - -#endif /* OPENSSL_CONFIGURATION_H */ +/* + * WARNING: do not edit! + * Generated by configdata.pm from Configurations\common0.tmpl, Configurations\windows-makefile.tmpl + * via makefile.in + * + * Copyright 2016-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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_CONFIGURATION_H +# define OPENSSL_CONFIGURATION_H +# pragma once + +# ifdef __cplusplus +extern "C" { +# endif + +# ifdef OPENSSL_ALGORITHM_DEFINES +# error OPENSSL_ALGORITHM_DEFINES no longer supported +# endif + +/* + * OpenSSL was configured with the following options: + */ + +#if defined(_WIN64) + +# ifndef OPENSSL_SYS_WIN64A +# define OPENSSL_SYS_WIN64A 1 +# endif + +#elif defined(_WIN32) + +# ifndef OPENSSL_SYS_WIN32 +# define OPENSSL_SYS_WIN32 1 +# endif + +#endif + +#if defined(_WIN64) || defined(_WIN32) + +# ifndef OPENSSL_THREADS +# define OPENSSL_THREADS +# endif + + +#define OPENSSL_SYS_WINDOWS +#define OPENSSL_NO_TS + +#endif + +# define OPENSSL_CONFIGURED_API 30300 +# ifndef OPENSSL_RAND_SEED_OS +# define OPENSSL_RAND_SEED_OS +# endif +# ifndef OPENSSL_NO_ACVP_TESTS +# define OPENSSL_NO_ACVP_TESTS +# endif +# ifndef OPENSSL_NO_AFALGENG +# define OPENSSL_NO_AFALGENG +# endif +# ifndef OPENSSL_NO_ASAN +# define OPENSSL_NO_ASAN +# endif +# ifndef OPENSSL_NO_BROTLI +# define OPENSSL_NO_BROTLI +# endif +# ifndef OPENSSL_NO_BROTLI_DYNAMIC +# define OPENSSL_NO_BROTLI_DYNAMIC +# endif +# ifndef OPENSSL_NO_CRYPTO_MDEBUG +# define OPENSSL_NO_CRYPTO_MDEBUG +# endif +# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE +# define OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE +# endif +# ifndef OPENSSL_NO_DEFAULT_THREAD_POOL +# define OPENSSL_NO_DEFAULT_THREAD_POOL +# endif +# ifndef OPENSSL_NO_DEVCRYPTOENG +# define OPENSSL_NO_DEVCRYPTOENG +# endif +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +# endif +# ifndef OPENSSL_NO_EGD +# define OPENSSL_NO_EGD +# endif +# ifndef OPENSSL_NO_EXTERNAL_TESTS +# define OPENSSL_NO_EXTERNAL_TESTS +# endif +# ifndef OPENSSL_NO_FIPS_SECURITYCHECKS +# define OPENSSL_NO_FIPS_SECURITYCHECKS +# endif +# ifndef OPENSSL_NO_FUZZ_AFL +# define OPENSSL_NO_FUZZ_AFL +# endif +# ifndef OPENSSL_NO_FUZZ_LIBFUZZER +# define OPENSSL_NO_FUZZ_LIBFUZZER +# endif +# ifndef OPENSSL_NO_KTLS +# define OPENSSL_NO_KTLS +# endif +# ifndef OPENSSL_NO_LOADERENG +# define OPENSSL_NO_LOADERENG +# endif +# ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +# endif +# ifndef OPENSSL_NO_MSAN +# define OPENSSL_NO_MSAN +# endif +# ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +# endif +# ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +# endif +# ifndef OPENSSL_NO_SSL3 +# define OPENSSL_NO_SSL3 +# endif +# ifndef OPENSSL_NO_SSL3_METHOD +# define OPENSSL_NO_SSL3_METHOD +# endif +# ifndef OPENSSL_NO_TFO +# define OPENSSL_NO_TFO +# endif +# ifndef OPENSSL_NO_THREAD_POOL +# define OPENSSL_NO_THREAD_POOL +# endif +# ifndef OPENSSL_NO_TRACE +# define OPENSSL_NO_TRACE +# endif +# ifndef OPENSSL_NO_UBSAN +# define OPENSSL_NO_UBSAN +# endif +# ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +# endif +# ifndef OPENSSL_NO_UPLINK +# define OPENSSL_NO_UPLINK +# endif +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +# endif +# ifndef OPENSSL_NO_ZLIB +# define OPENSSL_NO_ZLIB +# endif +# ifndef OPENSSL_NO_ZLIB_DYNAMIC +# define OPENSSL_NO_ZLIB_DYNAMIC +# endif +# ifndef OPENSSL_NO_ZSTD +# define OPENSSL_NO_ZSTD +# endif +# ifndef OPENSSL_NO_ZSTD_DYNAMIC +# define OPENSSL_NO_ZSTD_DYNAMIC +# endif +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +# define OPENSSL_NO_DYNAMIC_ENGINE +# endif +# ifndef OPENSSL_NO_STATIC_ENGINE +# define OPENSSL_NO_STATIC_ENGINE +# endif +# ifndef OPENSSL_NO_QLOG +# define OPENSSL_NO_QLOG +# endif + + +/* Generate 80386 code? */ +# undef I386_ONLY + +#define ENGINESDIR "C:\\engines-3" +#define MODULESDIR "C:\\ossl-modules" +#define OPENSSLDIR "C:\\SSL" + +/* + * The following are cipher-specific, but are part of the public API. + */ +#if defined(_WIN64) || defined(_M_ARM64) + +# if !defined(OPENSSL_SYS_UEFI) +# undef BN_LLONG +/* Only one for the following should be defined */ +# undef SIXTY_FOUR_BIT_LONG +# define SIXTY_FOUR_BIT +# undef THIRTY_TWO_BIT +# endif + +#elif defined(_WIN32) + +# if !defined(OPENSSL_SYS_UEFI) +# define BN_LLONG +/* Only one for the following should be defined */ +# undef SIXTY_FOUR_BIT_LONG +# undef SIXTY_FOUR_BIT +# define THIRTY_TWO_BIT +# endif + +#endif + +#if defined(_WIN64) || defined(_WIN32) + +# define RC4_INT unsigned int + +#define _setmode setmode +#define _strdup strdup + +#elif defined(_M_ARM64) + +# define RC4_INT unsigned char + +# ifndef OPENSSL_NO_ASM +# define OPENSSL_NO_ASM +# endif +# ifndef OPENSSL_NO_RFC3779 +# define OPENSSL_NO_RFC3779 +# endif +# ifndef OPENSSL_NO_SSL_TRACE +# define OPENSSL_NO_SSL_TRACE +# endif +# ifndef OPENSSL_NO_DEFAULT_THREAD_POOL +# define OPENSSL_NO_DEFAULT_THREAD_POOL +# endif +# ifndef OPENSSL_NO_LOADERENG +# define OPENSSL_NO_LOADERENG +# endif +# ifndef OPENSSL_NO_TFO +# define OPENSSL_NO_TFO +# endif +# ifndef OPENSSL_NO_THREAD_POOL +# define OPENSSL_NO_THREAD_POOL +# endif + +#endif + +# if defined(OPENSSL_NO_COMP) || (defined(OPENSSL_NO_BROTLI) && defined(OPENSSL_NO_ZSTD) && defined(OPENSSL_NO_ZLIB)) +# define OPENSSL_NO_COMP_ALG +# else +# undef OPENSSL_NO_COMP_ALG +# endif + +# ifdef __cplusplus +} +# endif + +#ifndef _timeb +#define _timeb timeb +#endif + +#ifndef _ftime +#define _ftime ftime +#endif + +#endif /* OPENSSL_CONFIGURATION_H */ diff --git a/libs/openssl-3/include/openssl/core_dispatch.h b/libs/openssl-3/include/openssl/core_dispatch.h index 9b03f20c3..a5bc2cf75 100644 --- a/libs/openssl-3/include/openssl/core_dispatch.h +++ b/libs/openssl-3/include/openssl/core_dispatch.h @@ -300,6 +300,7 @@ OSSL_CORE_MAKE_FUNC(int, provider_self_test, (void *provctx)) # define OSSL_FUNC_DIGEST_GETTABLE_PARAMS 11 # define OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS 12 # define OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS 13 +# define OSSL_FUNC_DIGEST_SQUEEZE 14 OSSL_CORE_MAKE_FUNC(void *, digest_newctx, (void *provctx)) OSSL_CORE_MAKE_FUNC(int, digest_init, (void *dctx, const OSSL_PARAM params[])) @@ -308,6 +309,9 @@ OSSL_CORE_MAKE_FUNC(int, digest_update, OSSL_CORE_MAKE_FUNC(int, digest_final, (void *dctx, unsigned char *out, size_t *outl, size_t outsz)) +OSSL_CORE_MAKE_FUNC(int, digest_squeeze, + (void *dctx, + unsigned char *out, size_t *outl, size_t outsz)) OSSL_CORE_MAKE_FUNC(int, digest_digest, (void *provctx, const unsigned char *in, size_t inl, unsigned char *out, size_t *outl, size_t outsz)) diff --git a/libs/openssl-3/include/openssl/core_names.h b/libs/openssl-3/include/openssl/core_names.h index c52330d24..81adbfa11 100644 --- a/libs/openssl-3/include/openssl/core_names.h +++ b/libs/openssl-3/include/openssl/core_names.h @@ -384,6 +384,7 @@ extern "C" { # define OSSL_PKEY_PARAM_RSA_COEFFICIENT8 "rsa-coefficient8" # define OSSL_PKEY_PARAM_RSA_COEFFICIENT9 "rsa-coefficient9" # define OSSL_PKEY_PARAM_RSA_D "d" +# define OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ "rsa-derive-from-pq" # define OSSL_PKEY_PARAM_RSA_DIGEST OSSL_PKEY_PARAM_DIGEST # define OSSL_PKEY_PARAM_RSA_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES # define OSSL_PKEY_PARAM_RSA_E "e" diff --git a/libs/openssl-3/include/openssl/dh.h b/libs/openssl-3/include/openssl/dh.h index f1c0ed06b..97024929a 100644 --- a/libs/openssl-3/include/openssl/dh.h +++ b/libs/openssl-3/include/openssl/dh.h @@ -25,7 +25,11 @@ extern "C" { #include -/* DH parameter generation types used by EVP_PKEY_CTX_set_dh_paramgen_type() */ +/* + * DH parameter generation types used by EVP_PKEY_CTX_set_dh_paramgen_type() + * Note that additions/changes to this set of values requires corresponding + * adjustments to range checks in dh_gen() + */ # define DH_PARAMGEN_TYPE_GENERATOR 0 /* Use a safe prime generator */ # define DH_PARAMGEN_TYPE_FIPS_186_2 1 /* Use FIPS186-2 standard */ # define DH_PARAMGEN_TYPE_FIPS_186_4 2 /* Use FIPS186-4 standard */ diff --git a/libs/openssl-3/include/openssl/err.h b/libs/openssl-3/include/openssl/err.h index 205f8c550..8f74f4805 100644 --- a/libs/openssl-3/include/openssl/err.h +++ b/libs/openssl-3/include/openssl/err.h @@ -372,7 +372,7 @@ typedef struct ERR_string_data_st { } ERR_STRING_DATA; DEFINE_LHASH_OF_INTERNAL(ERR_STRING_DATA); -#define lh_ERR_STRING_DATA_new(hfn, cmp) ((LHASH_OF(ERR_STRING_DATA) *)OPENSSL_LH_new(ossl_check_ERR_STRING_DATA_lh_hashfunc_type(hfn), ossl_check_ERR_STRING_DATA_lh_compfunc_type(cmp))) +#define lh_ERR_STRING_DATA_new(hfn, cmp) ((LHASH_OF(ERR_STRING_DATA) *)OPENSSL_LH_set_thunks(OPENSSL_LH_new(ossl_check_ERR_STRING_DATA_lh_hashfunc_type(hfn), ossl_check_ERR_STRING_DATA_lh_compfunc_type(cmp)), lh_ERR_STRING_DATA_hash_thunk, lh_ERR_STRING_DATA_comp_thunk, lh_ERR_STRING_DATA_doall_thunk, lh_ERR_STRING_DATA_doall_arg_thunk)) #define lh_ERR_STRING_DATA_free(lh) OPENSSL_LH_free(ossl_check_ERR_STRING_DATA_lh_type(lh)) #define lh_ERR_STRING_DATA_flush(lh) OPENSSL_LH_flush(ossl_check_ERR_STRING_DATA_lh_type(lh)) #define lh_ERR_STRING_DATA_insert(lh, ptr) ((ERR_STRING_DATA *)OPENSSL_LH_insert(ossl_check_ERR_STRING_DATA_lh_type(lh), ossl_check_ERR_STRING_DATA_lh_plain_type(ptr))) @@ -497,6 +497,7 @@ int ERR_set_mark(void); int ERR_pop_to_mark(void); int ERR_clear_last_mark(void); int ERR_count_to_mark(void); +int ERR_pop(void); ERR_STATE *OSSL_ERR_STATE_new(void); void OSSL_ERR_STATE_save(ERR_STATE *es); diff --git a/libs/openssl-3/include/openssl/evp.h b/libs/openssl-3/include/openssl/evp.h index ea7620d63..f70b9d744 100644 --- a/libs/openssl-3/include/openssl/evp.h +++ b/libs/openssl-3/include/openssl/evp.h @@ -729,8 +729,10 @@ __owur int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); __owur int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); __owur int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); -__owur int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, - size_t len); +__owur int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *out, + size_t outlen); +__owur int EVP_DigestSqueeze(EVP_MD_CTX *ctx, unsigned char *out, + size_t outlen); __owur EVP_MD *EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); diff --git a/libs/openssl-3/include/openssl/hpke.h b/libs/openssl-3/include/openssl/hpke.h index ee079ece5..482acd22c 100644 --- a/libs/openssl-3/include/openssl/hpke.h +++ b/libs/openssl-3/include/openssl/hpke.h @@ -68,7 +68,7 @@ /* * Roles for use in creating an OSSL_HPKE_CTX, most - * important use of this is to control nonce re-use. + * important use of this is to control nonce reuse. */ # define OSSL_HPKE_ROLE_SENDER 0 # define OSSL_HPKE_ROLE_RECEIVER 1 diff --git a/libs/openssl-3/include/openssl/http.h b/libs/openssl-3/include/openssl/http.h index a3cbf15f5..8f4e9da30 100644 --- a/libs/openssl-3/include/openssl/http.h +++ b/libs/openssl-3/include/openssl/http.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. * Copyright Siemens AG 2018-2020 * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -37,6 +37,8 @@ extern "C" { #define OSSL_HTTP_DEFAULT_MAX_LINE_LEN (4 * 1024) #define OSSL_HTTP_DEFAULT_MAX_RESP_LEN (100 * 1024) +#define OSSL_HTTP_DEFAULT_MAX_RESP_HDR_LINES 256 + /* Low-level HTTP API */ OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int buf_size); @@ -105,6 +107,8 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost, const char *OSSL_HTTP_adapt_proxy(const char *proxy, const char *no_proxy, const char *server, int use_ssl); +void OSSL_HTTP_REQ_CTX_set_max_response_hdr_lines(OSSL_HTTP_REQ_CTX *rctx, + size_t count); # endif /* !defined(OPENSSL_NO_HTTP) */ # ifdef __cplusplus diff --git a/libs/openssl-3/include/openssl/httperr.h b/libs/openssl-3/include/openssl/httperr.h index ee0895920..ae7f00cac 100644 --- a/libs/openssl-3/include/openssl/httperr.h +++ b/libs/openssl-3/include/openssl/httperr.h @@ -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 @@ -44,6 +44,7 @@ # define HTTP_R_REDIRECTION_NOT_ENABLED 116 # define HTTP_R_RESPONSE_LINE_TOO_LONG 113 # define HTTP_R_RESPONSE_PARSE_ERROR 104 +# define HTTP_R_RESPONSE_TOO_MANY_HDRLINES 130 # define HTTP_R_RETRY_TIMEOUT 129 # define HTTP_R_SERVER_CANCELED_CONNECTION 127 # define HTTP_R_SOCK_NOT_SUPPORTED 122 diff --git a/libs/openssl-3/include/openssl/lhash.h b/libs/openssl-3/include/openssl/lhash.h index a0b0a48d8..93044eec7 100644 --- a/libs/openssl-3/include/openssl/lhash.h +++ b/libs/openssl-3/include/openssl/lhash.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 @@ -34,9 +34,13 @@ extern "C" { typedef struct lhash_node_st OPENSSL_LH_NODE; typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *); +typedef int (*OPENSSL_LH_COMPFUNCTHUNK) (const void *, const void *, OPENSSL_LH_COMPFUNC cfn); typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *); +typedef unsigned long (*OPENSSL_LH_HASHFUNCTHUNK) (const void *, OPENSSL_LH_HASHFUNC hfn); typedef void (*OPENSSL_LH_DOALL_FUNC) (void *); +typedef void (*OPENSSL_LH_DOALL_FUNC_THUNK) (void *, OPENSSL_LH_DOALL_FUNC doall); typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *); +typedef void (*OPENSSL_LH_DOALL_FUNCARG_THUNK) (void *, void *, OPENSSL_LH_DOALL_FUNCARG doall); typedef struct lhash_st OPENSSL_LHASH; /* @@ -82,13 +86,23 @@ typedef struct lhash_st OPENSSL_LHASH; int OPENSSL_LH_error(OPENSSL_LHASH *lh); OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c); +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); void OPENSSL_LH_free(OPENSSL_LHASH *lh); void OPENSSL_LH_flush(OPENSSL_LHASH *lh); void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data); void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data); void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data); void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func); -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); +void OPENSSL_LH_doall_arg_thunk(OPENSSL_LHASH *lh, + OPENSSL_LH_DOALL_FUNCARG_THUNK daaw, + OPENSSL_LH_DOALL_FUNCARG fn, void *arg); + unsigned long OPENSSL_LH_strhash(const char *c); unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh); unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh); @@ -142,6 +156,26 @@ OSSL_DEPRECATEDIN_3_1 void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH * typedef int (*lh_##type##_compfunc)(const type *a, const type *b); \ typedef unsigned long (*lh_##type##_hashfunc)(const type *a); \ typedef void (*lh_##type##_doallfunc)(type *a); \ + static ossl_inline unsigned long lh_##type##_hash_thunk(const void *data, OPENSSL_LH_HASHFUNC hfn) \ + { \ + unsigned long (*hfn_conv)(const type *) = (unsigned long (*)(const type *))hfn; \ + return hfn_conv((const type *)data); \ + } \ + static ossl_inline int lh_##type##_comp_thunk(const void *da, const void *db, OPENSSL_LH_COMPFUNC cfn) \ + { \ + int (*cfn_conv)(const type *, const type *) = (int (*)(const type *, const type *))cfn; \ + return cfn_conv((const type *)da, (const type *)db); \ + } \ + static ossl_inline void lh_##type##_doall_thunk(void *node, OPENSSL_LH_DOALL_FUNC doall) \ + { \ + void (*doall_conv)(type *) = (void (*)(type *))doall; \ + doall_conv((type *)node); \ + } \ + static ossl_inline void lh_##type##_doall_arg_thunk(void *node, void *arg, OPENSSL_LH_DOALL_FUNCARG doall) \ + { \ + void (*doall_conv)(type *, void *) = (void (*)(type *, void *))doall; \ + doall_conv((type *)node, arg); \ + } \ static ossl_unused ossl_inline type *\ ossl_check_##type##_lh_plain_type(type *ptr) \ { \ @@ -204,12 +238,16 @@ OSSL_DEPRECATEDIN_3_1 void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH * LHASH_OF(type) { \ union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; \ }; \ - static ossl_unused ossl_inline LHASH_OF(type) * \ - lh_##type##_new(unsigned long (*hfn)(const type *), \ - int (*cfn)(const type *, const type *)) \ + static unsigned long \ + lh_##type##_hfn_thunk(const void *data, OPENSSL_LH_HASHFUNC hfn) \ { \ - return (LHASH_OF(type) *) \ - OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \ + unsigned long (*hfn_conv)(const type *) = (unsigned long (*)(const type *))hfn; \ + return hfn_conv((const type *)data); \ + } \ + static int lh_##type##_cfn_thunk(const void *da, const void *db, OPENSSL_LH_COMPFUNC cfn) \ + { \ + int (*cfn_conv)(const type *, const type *) = (int (*)(const type *, const type *))cfn; \ + return cfn_conv((const type *)da, (const type *)db); \ } \ static ossl_unused ossl_inline void \ lh_##type##_free(LHASH_OF(type) *lh) \ @@ -257,10 +295,31 @@ OSSL_DEPRECATEDIN_3_1 void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH * OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \ } \ static ossl_unused ossl_inline void \ + lh_##type##_doall_thunk(void *node, OPENSSL_LH_DOALL_FUNC doall) \ + { \ + void (*doall_conv)(type *) = (void (*)(type *))doall; \ + doall_conv((type *)node); \ + } \ + static ossl_unused ossl_inline void \ + lh_##type##_doall_arg_thunk(void *node, void *arg, OPENSSL_LH_DOALL_FUNCARG doall) \ + { \ + void (*doall_conv)(type *, void *) = (void (*)(type *, void *))doall; \ + doall_conv((type *)node, arg); \ + } \ + static ossl_unused ossl_inline void \ lh_##type##_doall(LHASH_OF(type) *lh, void (*doall)(type *)) \ { \ OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \ } \ + static ossl_unused ossl_inline LHASH_OF(type) * \ + lh_##type##_new(unsigned long (*hfn)(const type *), \ + int (*cfn)(const type *, const type *)) \ + { \ + return (LHASH_OF(type) *)OPENSSL_LH_set_thunks(OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn), \ + lh_##type##_hfn_thunk, lh_##type##_cfn_thunk, \ + lh_##type##_doall_thunk, \ + lh_##type##_doall_arg_thunk); \ + } \ static ossl_unused ossl_inline void \ lh_##type##_doall_arg(LHASH_OF(type) *lh, \ void (*doallarg)(type *, void *), void *arg) \ @@ -282,18 +341,26 @@ OSSL_DEPRECATEDIN_3_1 void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH * int_implement_lhash_doall(type, argtype, type) #define int_implement_lhash_doall(type, argtype, cbargtype) \ + static ossl_unused ossl_inline void \ + lh_##type##_doall_##argtype##_thunk(void *node, void *arg, OPENSSL_LH_DOALL_FUNCARG fn) \ + { \ + void (*fn_conv)(cbargtype *, argtype *) = (void (*)(cbargtype *, argtype *))fn; \ + fn_conv((cbargtype *)node, (argtype *)arg); \ + } \ static ossl_unused ossl_inline void \ lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \ void (*fn)(cbargtype *, argtype *), \ argtype *arg) \ { \ - OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, \ - (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \ + OPENSSL_LH_doall_arg_thunk((OPENSSL_LHASH *)lh, \ + lh_##type##_doall_##argtype##_thunk, \ + (OPENSSL_LH_DOALL_FUNCARG)fn, \ + (void *)arg); \ } \ LHASH_OF(type) DEFINE_LHASH_OF_INTERNAL(OPENSSL_STRING); -#define lh_OPENSSL_STRING_new(hfn, cmp) ((LHASH_OF(OPENSSL_STRING) *)OPENSSL_LH_new(ossl_check_OPENSSL_STRING_lh_hashfunc_type(hfn), ossl_check_OPENSSL_STRING_lh_compfunc_type(cmp))) +#define lh_OPENSSL_STRING_new(hfn, cmp) ((LHASH_OF(OPENSSL_STRING) *)OPENSSL_LH_set_thunks(OPENSSL_LH_new(ossl_check_OPENSSL_STRING_lh_hashfunc_type(hfn), ossl_check_OPENSSL_STRING_lh_compfunc_type(cmp)), lh_OPENSSL_STRING_hash_thunk, lh_OPENSSL_STRING_comp_thunk, lh_OPENSSL_STRING_doall_thunk, lh_OPENSSL_STRING_doall_arg_thunk)) #define lh_OPENSSL_STRING_free(lh) OPENSSL_LH_free(ossl_check_OPENSSL_STRING_lh_type(lh)) #define lh_OPENSSL_STRING_flush(lh) OPENSSL_LH_flush(ossl_check_OPENSSL_STRING_lh_type(lh)) #define lh_OPENSSL_STRING_insert(lh, ptr) ((OPENSSL_STRING *)OPENSSL_LH_insert(ossl_check_OPENSSL_STRING_lh_type(lh), ossl_check_OPENSSL_STRING_lh_plain_type(ptr))) @@ -308,7 +375,7 @@ DEFINE_LHASH_OF_INTERNAL(OPENSSL_STRING); #define lh_OPENSSL_STRING_set_down_load(lh, dl) OPENSSL_LH_set_down_load(ossl_check_OPENSSL_STRING_lh_type(lh), dl) #define lh_OPENSSL_STRING_doall(lh, dfn) OPENSSL_LH_doall(ossl_check_OPENSSL_STRING_lh_type(lh), ossl_check_OPENSSL_STRING_lh_doallfunc_type(dfn)) DEFINE_LHASH_OF_INTERNAL(OPENSSL_CSTRING); -#define lh_OPENSSL_CSTRING_new(hfn, cmp) ((LHASH_OF(OPENSSL_CSTRING) *)OPENSSL_LH_new(ossl_check_OPENSSL_CSTRING_lh_hashfunc_type(hfn), ossl_check_OPENSSL_CSTRING_lh_compfunc_type(cmp))) +#define lh_OPENSSL_CSTRING_new(hfn, cmp) ((LHASH_OF(OPENSSL_CSTRING) *)OPENSSL_LH_set_thunks(OPENSSL_LH_new(ossl_check_OPENSSL_CSTRING_lh_hashfunc_type(hfn), ossl_check_OPENSSL_CSTRING_lh_compfunc_type(cmp)), lh_OPENSSL_CSTRING_hash_thunk, lh_OPENSSL_CSTRING_comp_thunk, lh_OPENSSL_CSTRING_doall_thunk, lh_OPENSSL_CSTRING_doall_arg_thunk)) #define lh_OPENSSL_CSTRING_free(lh) OPENSSL_LH_free(ossl_check_OPENSSL_CSTRING_lh_type(lh)) #define lh_OPENSSL_CSTRING_flush(lh) OPENSSL_LH_flush(ossl_check_OPENSSL_CSTRING_lh_type(lh)) #define lh_OPENSSL_CSTRING_insert(lh, ptr) ((OPENSSL_CSTRING *)OPENSSL_LH_insert(ossl_check_OPENSSL_CSTRING_lh_type(lh), ossl_check_OPENSSL_CSTRING_lh_plain_type(ptr))) diff --git a/libs/openssl-3/include/openssl/obj_mac.h b/libs/openssl-3/include/openssl/obj_mac.h index e1b441b31..1b7d9240a 100644 --- a/libs/openssl-3/include/openssl/obj_mac.h +++ b/libs/openssl-3/include/openssl/obj_mac.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/objects/objects.pl * - * 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 * in the file LICENSE in the source distribution or at @@ -894,6 +894,10 @@ #define NID_id_ct_signedTAL 1284 #define OBJ_id_ct_signedTAL OBJ_id_smime_ct,50L +#define SN_id_ct_rpkiSignedPrefixList "id-ct-rpkiSignedPrefixList" +#define NID_id_ct_rpkiSignedPrefixList 1320 +#define OBJ_id_ct_rpkiSignedPrefixList OBJ_id_smime_ct,51L + #define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" #define NID_id_smime_aa_receiptRequest 212 #define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L diff --git a/libs/openssl-3/include/openssl/opensslconf.h b/libs/openssl-3/include/openssl/opensslconf.h index eb59e0a34..1e83371f1 100644 --- a/libs/openssl-3/include/openssl/opensslconf.h +++ b/libs/openssl-3/include/openssl/opensslconf.h @@ -1,17 +1,17 @@ -/* - * 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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_OPENSSLCONF_H -# define OPENSSL_OPENSSLCONF_H -# pragma once - -# include -# include - -#endif /* OPENSSL_OPENSSLCONF_H */ +/* + * 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_OPENSSLCONF_H +# define OPENSSL_OPENSSLCONF_H +# pragma once + +# include +# include + +#endif /* OPENSSL_OPENSSLCONF_H */ diff --git a/libs/openssl-3/include/openssl/opensslv.h b/libs/openssl-3/include/openssl/opensslv.h index 0e18c71a9..928006fa2 100644 --- a/libs/openssl-3/include/openssl/opensslv.h +++ b/libs/openssl-3/include/openssl/opensslv.h @@ -28,8 +28,8 @@ extern "C" { * These macros express version number MAJOR.MINOR.PATCH exactly */ # define OPENSSL_VERSION_MAJOR 3 -# define OPENSSL_VERSION_MINOR 2 -# define OPENSSL_VERSION_PATCH 2 +# define OPENSSL_VERSION_MINOR 3 +# define OPENSSL_VERSION_PATCH 1 /* * Additional version information @@ -74,8 +74,8 @@ extern "C" { * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and * OPENSSL_VERSION_BUILD_METADATA_STR appended. */ -# define OPENSSL_VERSION_STR "3.2.2" -# define OPENSSL_FULL_VERSION_STR "3.2.2" +# define OPENSSL_VERSION_STR "3.3.1" +# define OPENSSL_FULL_VERSION_STR "3.3.1" /* * SECTION 3: ADDITIONAL METADATA @@ -88,7 +88,7 @@ extern "C" { * SECTION 4: BACKWARD COMPATIBILITY */ -# define OPENSSL_VERSION_TEXT "OpenSSL 3.2.2 4 Jun 2024" +# define OPENSSL_VERSION_TEXT "OpenSSL 3.3.1 4 Jun 2024" /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */ # ifdef OPENSSL_VERSION_PRE_RELEASE diff --git a/libs/openssl-3/include/openssl/pkcs7.h b/libs/openssl-3/include/openssl/pkcs7.h index dc43e7f06..d73b2610b 100644 --- a/libs/openssl-3/include/openssl/pkcs7.h +++ b/libs/openssl-3/include/openssl/pkcs7.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by makefile from include\openssl\pkcs7.h.in * - * 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 diff --git a/libs/openssl-3/include/openssl/quic.h b/libs/openssl-3/include/openssl/quic.h index 74a6345d5..3dc2f5e74 100644 --- a/libs/openssl-3/include/openssl/quic.h +++ b/libs/openssl-3/include/openssl/quic.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 @@ -24,11 +24,44 @@ extern "C" { * Method used for non-thread-assisted QUIC client operation. */ __owur const SSL_METHOD *OSSL_QUIC_client_method(void); + /* * Method used for thread-assisted QUIC client operation. */ __owur const SSL_METHOD *OSSL_QUIC_client_thread_method(void); +/* + * QUIC transport error codes (RFC 9000 s. 20.1) + */ +# define OSSL_QUIC_ERR_NO_ERROR 0x00 +# define OSSL_QUIC_ERR_INTERNAL_ERROR 0x01 +# define OSSL_QUIC_ERR_CONNECTION_REFUSED 0x02 +# define OSSL_QUIC_ERR_FLOW_CONTROL_ERROR 0x03 +# define OSSL_QUIC_ERR_STREAM_LIMIT_ERROR 0x04 +# define OSSL_QUIC_ERR_STREAM_STATE_ERROR 0x05 +# define OSSL_QUIC_ERR_FINAL_SIZE_ERROR 0x06 +# define OSSL_QUIC_ERR_FRAME_ENCODING_ERROR 0x07 +# define OSSL_QUIC_ERR_TRANSPORT_PARAMETER_ERROR 0x08 +# define OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR 0x09 +# define OSSL_QUIC_ERR_PROTOCOL_VIOLATION 0x0A +# define OSSL_QUIC_ERR_INVALID_TOKEN 0x0B +# define OSSL_QUIC_ERR_APPLICATION_ERROR 0x0C +# define OSSL_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED 0x0D +# define OSSL_QUIC_ERR_KEY_UPDATE_ERROR 0x0E +# define OSSL_QUIC_ERR_AEAD_LIMIT_REACHED 0x0F +# define OSSL_QUIC_ERR_NO_VIABLE_PATH 0x10 + +/* Inclusive range for handshake-specific errors. */ +# define OSSL_QUIC_ERR_CRYPTO_ERR_BEGIN 0x0100 +# define OSSL_QUIC_ERR_CRYPTO_ERR_END 0x01FF + +# define OSSL_QUIC_ERR_CRYPTO_ERR(X) \ + (OSSL_QUIC_ERR_CRYPTO_ERR_BEGIN + (X)) + +/* Local errors. */ +# define OSSL_QUIC_LOCAL_ERR_IDLE_TIMEOUT \ + ((uint64_t)0xFFFFFFFFFFFFFFFFULL) + # ifdef __cplusplus } # endif diff --git a/libs/openssl-3/include/openssl/self_test.h b/libs/openssl-3/include/openssl/self_test.h index 337a3190c..17822049a 100644 --- a/libs/openssl-3/include/openssl/self_test.h +++ b/libs/openssl-3/include/openssl/self_test.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 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 @@ -46,6 +46,7 @@ extern "C" { # define OSSL_SELF_TEST_DESC_INTEGRITY_HMAC "HMAC" # define OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1 "RSA" # define OSSL_SELF_TEST_DESC_PCT_ECDSA "ECDSA" +# define OSSL_SELF_TEST_DESC_PCT_EDDSA "EDDSA" # define OSSL_SELF_TEST_DESC_PCT_DSA "DSA" # define OSSL_SELF_TEST_DESC_CIPHER_AES_GCM "AES_GCM" # define OSSL_SELF_TEST_DESC_CIPHER_AES_ECB "AES_ECB_Decrypt" @@ -71,6 +72,7 @@ extern "C" { # define OSSL_SELF_TEST_DESC_KDF_SSHKDF "SSHKDF" # define OSSL_SELF_TEST_DESC_KDF_TLS12_PRF "TLS12_PRF" # define OSSL_SELF_TEST_DESC_KDF_KBKDF "KBKDF" +# define OSSL_SELF_TEST_DESC_KDF_KBKDF_KMAC "KBKDF_KMAC" # define OSSL_SELF_TEST_DESC_KDF_TLS13_EXTRACT "TLS13_KDF_EXTRACT" # define OSSL_SELF_TEST_DESC_KDF_TLS13_EXPAND "TLS13_KDF_EXPAND" # define OSSL_SELF_TEST_DESC_RNG "RNG" diff --git a/libs/openssl-3/include/openssl/ssl.h b/libs/openssl-3/include/openssl/ssl.h index ba7f45f8d..fdb87b11f 100644 --- a/libs/openssl-3/include/openssl/ssl.h +++ b/libs/openssl-3/include/openssl/ssl.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by makefile from include\openssl\ssl.h.in * - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -449,6 +449,8 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); /* Enable KTLS TX zerocopy on Linux */ # define SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE SSL_OP_BIT(34) +#define SSL_OP_PREFER_NO_DHE_KEX SSL_OP_BIT(35) + /* * Option "collections." */ @@ -1761,6 +1763,9 @@ __owur long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); __owur int SSL_SESSION_get_protocol_version(const SSL_SESSION *s); __owur int SSL_SESSION_set_protocol_version(SSL_SESSION *s, int version); +__owur time_t SSL_SESSION_get_time_ex(const SSL_SESSION *s); +__owur time_t SSL_SESSION_set_time_ex(SSL_SESSION *s, time_t t); + __owur const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s); __owur int SSL_SESSION_set1_hostname(SSL_SESSION *s, const char *hostname); void SSL_SESSION_get0_alpn_selected(const SSL_SESSION *s, @@ -2014,6 +2019,12 @@ long SSL_callback_ctrl(SSL *, int, void (*)(void)); long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); +# define SSL_WRITE_FLAG_CONCLUDE (1U << 0) + +__owur int SSL_write_ex2(SSL *s, const void *buf, size_t num, + uint64_t flags, + size_t *written); + # define SSL_EARLY_DATA_NOT_SENT 0 # define SSL_EARLY_DATA_REJECTED 1 # define SSL_EARLY_DATA_ACCEPTED 2 @@ -2430,6 +2441,124 @@ __owur int SSL_get_conn_close_info(SSL *ssl, SSL_CONN_CLOSE_INFO *info, size_t info_len); +# define SSL_VALUE_CLASS_GENERIC 0 +# define SSL_VALUE_CLASS_FEATURE_REQUEST 1 +# define SSL_VALUE_CLASS_FEATURE_PEER_REQUEST 2 +# define SSL_VALUE_CLASS_FEATURE_NEGOTIATED 3 + +# define SSL_VALUE_NONE 0 +# define SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL 1 +# define SSL_VALUE_QUIC_STREAM_BIDI_REMOTE_AVAIL 2 +# define SSL_VALUE_QUIC_STREAM_UNI_LOCAL_AVAIL 3 +# define SSL_VALUE_QUIC_STREAM_UNI_REMOTE_AVAIL 4 +# define SSL_VALUE_QUIC_IDLE_TIMEOUT 5 +# define SSL_VALUE_EVENT_HANDLING_MODE 6 +# define SSL_VALUE_STREAM_WRITE_BUF_SIZE 7 +# define SSL_VALUE_STREAM_WRITE_BUF_USED 8 +# define SSL_VALUE_STREAM_WRITE_BUF_AVAIL 9 + +# define SSL_VALUE_EVENT_HANDLING_MODE_INHERIT 0 +# define SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT 1 +# define SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT 2 + +int SSL_get_value_uint(SSL *s, uint32_t class_, uint32_t id, uint64_t *v); +int SSL_set_value_uint(SSL *s, uint32_t class_, uint32_t id, uint64_t v); + +# define SSL_get_generic_value_uint(ssl, id, v) \ + SSL_get_value_uint((ssl), SSL_VALUE_CLASS_GENERIC, (id), (v)) +# define SSL_set_generic_value_uint(ssl, id, v) \ + SSL_set_value_uint((ssl), SSL_VALUE_CLASS_GENERIC, (id), (v)) +# define SSL_get_feature_request_uint(ssl, id, v) \ + SSL_get_value_uint((ssl), SSL_VALUE_CLASS_FEATURE_REQUEST, (id), (v)) +# define SSL_set_feature_request_uint(ssl, id, v) \ + SSL_set_value_uint((ssl), SSL_VALUE_CLASS_FEATURE_REQUEST, (id), (v)) +# define SSL_get_feature_peer_request_uint(ssl, id, v) \ + SSL_get_value_uint((ssl), SSL_VALUE_CLASS_FEATURE_PEER_REQUEST, (id), (v)) +# define SSL_get_feature_negotiated_uint(ssl, id, v) \ + SSL_get_value_uint((ssl), SSL_VALUE_CLASS_FEATURE_NEGOTIATED, (id), (v)) + +# define SSL_get_quic_stream_bidi_local_avail(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL, \ + (value)) +# define SSL_get_quic_stream_bidi_remote_avail(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_QUIC_STREAM_BIDI_REMOTE_AVAIL, \ + (value)) +# define SSL_get_quic_stream_uni_local_avail(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_QUIC_STREAM_UNI_LOCAL_AVAIL, \ + (value)) +# define SSL_get_quic_stream_uni_remote_avail(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_QUIC_STREAM_UNI_REMOTE_AVAIL, \ + (value)) + +# define SSL_get_event_handling_mode(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_EVENT_HANDLING_MODE, \ + (value)) +# define SSL_set_event_handling_mode(ssl, value) \ + SSL_set_generic_value_uint((ssl), SSL_VALUE_EVENT_HANDLING_MODE, \ + (value)) + +# define SSL_get_stream_write_buf_size(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_STREAM_WRITE_BUF_SIZE, \ + (value)) +# define SSL_get_stream_write_buf_used(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_STREAM_WRITE_BUF_USED, \ + (value)) +# define SSL_get_stream_write_buf_avail(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_STREAM_WRITE_BUF_AVAIL, \ + (value)) + +# define SSL_POLL_EVENT_NONE 0 + +# define SSL_POLL_EVENT_F (1U << 0) /* F (Failure) */ +# define SSL_POLL_EVENT_EL (1U << 1) /* EL (Exception on Listener) */ +# define SSL_POLL_EVENT_EC (1U << 2) /* EC (Exception on Conn) */ +# define SSL_POLL_EVENT_ECD (1U << 3) /* ECD (Exception on Conn Drained) */ +# define SSL_POLL_EVENT_ER (1U << 4) /* ER (Exception on Read) */ +# define SSL_POLL_EVENT_EW (1U << 5) /* EW (Exception on Write) */ +# define SSL_POLL_EVENT_R (1U << 6) /* R (Readable) */ +# define SSL_POLL_EVENT_W (1U << 7) /* W (Writable) */ +# define SSL_POLL_EVENT_IC (1U << 8) /* IC (Incoming Connection) */ +# define SSL_POLL_EVENT_ISB (1U << 9) /* ISB (Incoming Stream: Bidi) */ +# define SSL_POLL_EVENT_ISU (1U << 10) /* ISU (Incoming Stream: Uni) */ +# define SSL_POLL_EVENT_OSB (1U << 11) /* OSB (Outgoing Stream: Bidi) */ +# define SSL_POLL_EVENT_OSU (1U << 12) /* OSU (Outgoing Stream: Uni) */ + +# define SSL_POLL_EVENT_RW (SSL_POLL_EVENT_R | SSL_POLL_EVENT_W) +# define SSL_POLL_EVENT_RE (SSL_POLL_EVENT_R | SSL_POLL_EVENT_ER) +# define SSL_POLL_EVENT_WE (SSL_POLL_EVENT_W | SSL_POLL_EVENT_EW) +# define SSL_POLL_EVENT_RWE (SSL_POLL_EVENT_RE | SSL_POLL_EVENT_WE) +# define SSL_POLL_EVENT_E (SSL_POLL_EVENT_EL | SSL_POLL_EVENT_EC \ + | SSL_POLL_EVENT_ER | SSL_POLL_EVENT_EW) +# define SSL_POLL_EVENT_IS (SSL_POLL_EVENT_ISB | SSL_POLL_EVENT_ISU) +# define SSL_POLL_EVENT_ISE (SSL_POLL_EVENT_IS | SSL_POLL_EVENT_EC) +# define SSL_POLL_EVENT_I (SSL_POLL_EVENT_IS | SSL_POLL_EVENT_IC) +# define SSL_POLL_EVENT_OS (SSL_POLL_EVENT_OSB | SSL_POLL_EVENT_OSU) +# define SSL_POLL_EVENT_OSE (SSL_POLL_EVENT_OS | SSL_POLL_EVENT_EC) + +typedef struct ssl_poll_item_st { + BIO_POLL_DESCRIPTOR desc; + uint64_t events, revents; +} SSL_POLL_ITEM; + +# define SSL_POLL_FLAG_NO_HANDLE_EVENTS (1U << 0) + +__owur int SSL_poll(SSL_POLL_ITEM *items, + size_t num_items, + size_t stride, + const struct timeval *timeout, + uint64_t flags, + size_t *result_count); + +static ossl_inline ossl_unused BIO_POLL_DESCRIPTOR +SSL_as_poll_descriptor(SSL *s) +{ + BIO_POLL_DESCRIPTOR d; + + d.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + d.value.ssl = s; + return d; +} + # ifndef OPENSSL_NO_DEPRECATED_1_1_0 # define SSL_cache_hit(s) SSL_session_reused(s) # endif diff --git a/libs/openssl-3/include/openssl/sslerr.h b/libs/openssl-3/include/openssl/sslerr.h index e330fa725..ec35df64e 100644 --- a/libs/openssl-3/include/openssl/sslerr.h +++ b/libs/openssl-3/include/openssl/sslerr.h @@ -125,6 +125,8 @@ # define SSL_R_EXT_LENGTH_MISMATCH 163 # define SSL_R_FAILED_TO_GET_PARAMETER 316 # define SSL_R_FAILED_TO_INIT_ASYNC 405 +# define SSL_R_FEATURE_NEGOTIATION_NOT_COMPLETE 417 +# define SSL_R_FEATURE_NOT_RENEGOTIABLE 413 # define SSL_R_FRAGMENTED_CLIENT_HELLO 401 # define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 # define SSL_R_HTTPS_PROXY_REQUEST 155 @@ -225,6 +227,7 @@ # define SSL_R_PEM_NAME_BAD_PREFIX 391 # define SSL_R_PEM_NAME_TOO_SHORT 392 # define SSL_R_PIPELINE_FAILURE 406 +# define SSL_R_POLL_REQUEST_NOT_SUPPORTED 418 # define SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR 278 # define SSL_R_PRIVATE_KEY_MISMATCH 288 # define SSL_R_PROTOCOL_IS_SHUTDOWN 207 @@ -348,10 +351,14 @@ # define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 # define SSL_R_UNSOLICITED_EXTENSION 217 # define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +# define SSL_R_UNSUPPORTED_CONFIG_VALUE 414 +# define SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS 415 +# define SSL_R_UNSUPPORTED_CONFIG_VALUE_OP 416 # define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 # define SSL_R_UNSUPPORTED_PROTOCOL 258 # define SSL_R_UNSUPPORTED_SSL_VERSION 259 # define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +# define SSL_R_UNSUPPORTED_WRITE_FLAG 412 # define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 # define SSL_R_VERSION_TOO_HIGH 166 # define SSL_R_VERSION_TOO_LOW 396 diff --git a/libs/openssl-3/include/openssl/sslerr_legacy.h b/libs/openssl-3/include/openssl/sslerr_legacy.h index ccf6d3b30..4c353671c 100644 --- a/libs/openssl-3/include/openssl/sslerr_legacy.h +++ b/libs/openssl-3/include/openssl/sslerr_legacy.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -143,7 +143,6 @@ OSSL_DEPRECATEDIN_3_0 int ERR_load_SSL_strings(void); # define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 0 # define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 0 # define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 0 -# define SSL_F_SSL_BAD_METHOD 0 # define SSL_F_SSL_BUILD_CERT_CHAIN 0 # define SSL_F_SSL_BYTES_TO_CIPHER_LIST 0 # define SSL_F_SSL_CACHE_CIPHERLIST 0 diff --git a/libs/openssl-3/include/openssl/x509_vfy.h b/libs/openssl-3/include/openssl/x509_vfy.h index b58c63101..7af2f387d 100644 --- a/libs/openssl-3/include/openssl/x509_vfy.h +++ b/libs/openssl-3/include/openssl/x509_vfy.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by makefile from include\openssl\x509_vfy.h.in * - * 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 @@ -497,6 +497,7 @@ int X509_STORE_lock(X509_STORE *xs); int X509_STORE_unlock(X509_STORE *xs); int X509_STORE_up_ref(X509_STORE *xs); STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *xs); +STACK_OF(X509_OBJECT) *X509_STORE_get1_objects(X509_STORE *xs); STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *xs); STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *xs, const X509_NAME *nm); diff --git a/libs/openssl-3/providers/fips/fipsprov.c b/libs/openssl-3/providers/fips/fipsprov.c index 7ec409710..86c18de28 100644 --- a/libs/openssl-3/providers/fips/fipsprov.c +++ b/libs/openssl-3/providers/fips/fipsprov.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 @@ -695,6 +695,8 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, } } + OPENSSL_cpuid_setup(); + /* Create a context. */ if ((*provctx = ossl_prov_ctx_new()) == NULL || (libctx = OSSL_LIB_CTX_new()) == NULL) diff --git a/libs/openssl-3/providers/fips/self_test_data.inc b/libs/openssl-3/providers/fips/self_test_data.inc index 2057378d3..d2a4778e9 100644 --- a/libs/openssl-3/providers/fips/self_test_data.inc +++ b/libs/openssl-3/providers/fips/self_test_data.inc @@ -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 @@ -497,6 +497,33 @@ static const ST_KAT_PARAM kbkdf_params[] = { ST_KAT_PARAM_END() }; +static const char kbkdf_kmac_mac[] = "KMAC128"; +static unsigned char kbkdf_kmac_label[] = { + 0xB5, 0xB5, 0xF3, 0x71, 0x9F, 0xBE, 0x5B, 0x3D, + 0x7B, 0x8D, 0x05, 0xA1, 0xD3, 0x25, 0x19, 0x50, +}; +static unsigned char kbkdf_kmac_context[] = { + 0x36, 0x60, 0x0E, 0xF3, 0xC3, 0x70, 0xB5, 0xEF, + 0x58, 0xBE, 0xF1, 0xBA, 0x1C, 0xF2, 0x74, 0xCB, +}; +static unsigned char kbkdf_kmac_key[] = { + 0xB2, 0x51, 0x4C, 0xC1, 0xD5, 0xCD, 0x7B, 0x6B, + 0xA3, 0x3C, 0x90, 0x05, 0xBD, 0xAC, 0x32, 0x2A, +}; +static unsigned char kbkdf_kmac_expected[] = { + 0xB1, 0x58, 0xEE, 0xB1, 0x34, 0xA4, 0xDD, 0x9D, + 0xAC, 0x52, 0xBD, 0x9E, 0x30, 0xE8, 0x0D, 0x76, + 0x42, 0x57, 0x01, 0x89, 0x5F, 0x82, 0x74, 0xB9, + 0xEB, 0x3E, 0x84, 0xD8, 0xA5, 0xDE, 0x6E, 0x54, +}; +static const ST_KAT_PARAM kbkdf_kmac_params[] = { + ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_MAC, kbkdf_kmac_mac), + ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, kbkdf_kmac_key), + ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SALT, kbkdf_kmac_label), + ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_INFO, kbkdf_kmac_context), + ST_KAT_PARAM_END() +}; + static const char tls13_kdf_digest[] = "SHA256"; static int tls13_kdf_extract_mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY; static int tls13_kdf_expand_mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY; @@ -587,6 +614,12 @@ static const ST_KAT_KDF st_kat_kdf_tests[] = kbkdf_params, ITM(kbkdf_expected) }, + { + OSSL_SELF_TEST_DESC_KDF_KBKDF_KMAC, + OSSL_KDF_NAME_KBKDF, + kbkdf_kmac_params, + ITM(kbkdf_kmac_expected) + }, { OSSL_SELF_TEST_DESC_KDF_HKDF, OSSL_KDF_NAME_HKDF, @@ -1400,14 +1433,14 @@ static const unsigned char ecd_prime_pub[] = { 0x82 }; static const unsigned char ecdsa_prime_expected_sig[] = { - 0x30, 0x3d, 0x02, 0x1d, 0x00, 0xd2, 0x4a, 0xc9, - 0x4f, 0xaf, 0xdb, 0x62, 0xfc, 0x41, 0x4a, 0x81, - 0x2a, 0x9f, 0xcf, 0xa3, 0xda, 0xfe, 0xa3, 0x49, - 0xbd, 0xea, 0xbf, 0x2a, 0x51, 0xb4, 0x0b, 0xc3, - 0xbc, 0x02, 0x1c, 0x7f, 0x30, 0xb7, 0xad, 0xab, - 0x09, 0x6e, 0x3c, 0xad, 0x7f, 0xf9, 0x5e, 0xaa, - 0xe2, 0x38, 0xe5, 0x29, 0x16, 0xc4, 0xc8, 0x77, - 0xa1, 0xf8, 0x60, 0x77, 0x39, 0x7a, 0xec + 0x30, 0x3d, 0x02, 0x1c, 0x48, 0x4f, 0x3c, 0x97, + 0x5b, 0xfa, 0x40, 0x6c, 0xdb, 0xd6, 0x70, 0xb5, + 0xbd, 0x2d, 0xd0, 0xc6, 0x22, 0x93, 0x5a, 0x88, + 0x56, 0xd0, 0xaf, 0x0a, 0x94, 0x92, 0x20, 0x01, + 0x02, 0x1d, 0x00, 0xa4, 0x80, 0xe0, 0x47, 0x88, + 0x8a, 0xef, 0x2a, 0x47, 0x9d, 0x81, 0x9a, 0xbf, + 0x45, 0xc3, 0x6f, 0x9e, 0x2e, 0xc1, 0x44, 0x9f, + 0xfd, 0x79, 0xdb, 0x90, 0x3e, 0xb9, 0xb2 }; static const ST_KAT_PARAM ecdsa_prime_key[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecd_prime_curve_name), @@ -1435,15 +1468,15 @@ static const unsigned char ecd_bin_pub[] = { 0x99, 0xb6, 0x8f, 0x80, 0x46 }; static const unsigned char ecdsa_bin_expected_sig[] = { - 0x30, 0x3f, 0x02, 0x1d, 0x08, 0x11, 0x7c, 0xcd, - 0xf4, 0xa1, 0x31, 0x9a, 0xc1, 0xfd, 0x50, 0x0e, - 0x5d, 0xa9, 0xb6, 0x0e, 0x95, 0x49, 0xe1, 0xbd, - 0x44, 0xe3, 0x5b, 0xa9, 0x35, 0x94, 0xa5, 0x2f, - 0xae, 0x02, 0x1e, 0x00, 0xe3, 0xba, 0xb8, 0x8f, - 0x4b, 0x05, 0x76, 0x88, 0x1e, 0x49, 0xd6, 0x62, - 0x76, 0xd3, 0x22, 0x4d, 0xa3, 0x7b, 0x04, 0xcc, - 0xfa, 0x7b, 0x41, 0x9b, 0x8c, 0xaf, 0x1b, 0x6d, - 0xbd + 0x30, 0x3f, 0x02, 0x1d, 0x58, 0xe9, 0xd0, 0x84, + 0x5c, 0xad, 0x29, 0x03, 0xf6, 0xa6, 0xbc, 0xe0, + 0x24, 0x6d, 0x9e, 0x79, 0x5d, 0x1e, 0xe8, 0x5a, + 0xc3, 0x31, 0x0a, 0xa9, 0xfb, 0xe3, 0x99, 0x54, + 0x11, 0x02, 0x1e, 0x00, 0xa3, 0x44, 0x28, 0xa3, + 0x70, 0x97, 0x98, 0x17, 0xd7, 0xa6, 0xad, 0x91, + 0xaf, 0x41, 0x69, 0xb6, 0x06, 0x99, 0x39, 0xc7, + 0x63, 0xa4, 0x6a, 0x81, 0xe4, 0x9a, 0x9d, 0x15, + 0x8b }; static const ST_KAT_PARAM ecdsa_bin_key[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecd_bin_curve_name), @@ -1571,14 +1604,14 @@ static const unsigned char dsa_priv[] = { 0x40, 0x7e, 0x5c, 0xb7 }; static const unsigned char dsa_expected_sig[] = { - 0x30, 0x3c, 0x02, 0x1c, 0x70, 0xa4, 0x77, 0xb6, - 0x02, 0xb5, 0xd3, 0x07, 0x21, 0x22, 0x2d, 0xe3, - 0x4f, 0x7d, 0xfd, 0xfd, 0x6b, 0x4f, 0x03, 0x27, - 0x4c, 0xd3, 0xb2, 0x8c, 0x7c, 0xc5, 0xc4, 0xdf, - 0x02, 0x1c, 0x11, 0x52, 0x65, 0x16, 0x9f, 0xbd, - 0x4c, 0xe5, 0xab, 0xb2, 0x01, 0xd0, 0x7a, 0x30, - 0x5c, 0xc5, 0xba, 0x22, 0xc6, 0x62, 0x7e, 0xa6, - 0x7d, 0x98, 0x96, 0xc9, 0x77, 0x00 + 0x30, 0x3c, 0x02, 0x1c, 0x69, 0xc6, 0xd6, 0x9e, + 0x2b, 0x91, 0xea, 0x72, 0xb3, 0x8b, 0x7c, 0x57, + 0x48, 0x75, 0xb7, 0x65, 0xc0, 0xb4, 0xf7, 0xbb, + 0x08, 0xa4, 0x95, 0x77, 0xfc, 0xa7, 0xed, 0x31, + 0x02, 0x1c, 0x4c, 0x2c, 0xff, 0xc6, 0x55, 0xeb, + 0x8f, 0xa7, 0x4f, 0x27, 0xd8, 0xec, 0xfd, 0x62, + 0x73, 0xf2, 0xd1, 0x55, 0xa5, 0xf0, 0x41, 0x68, + 0x34, 0x8d, 0x9e, 0x88, 0x08, 0x06 }; static const ST_KAT_PARAM dsa_key[] = { diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i.inc index 203664e62..f2353bb3b 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i.inc +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i.inc @@ -31,7 +31,41 @@ static const PROV_CCM_HW rv64i_zknd_zkne_ccm = { ossl_ccm_generic_gettag }; +/*- + * RISC-V RV64 ZVKNED support for AES CCM. + * This file is included by cipher_aes_ccm_hw.c + */ + +static int ccm_rv64i_zvkned_initkey(PROV_CCM_CTX *ctx, const unsigned char *key, + size_t keylen) +{ + PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx; + + /* Zvkned only supports 128 and 256 bit keys for key schedule generation. */ + if (keylen * 8 == 128 || keylen * 8 == 256) { + AES_HW_CCM_SET_KEY_FN(rv64i_zvkned_set_encrypt_key, rv64i_zvkned_encrypt, + NULL, NULL); + } else { + AES_HW_CCM_SET_KEY_FN(AES_set_encrypt_key, rv64i_zvkned_encrypt, NULL, NULL) + } + return 1; +} + +static const PROV_CCM_HW rv64i_zvkned_ccm = { + ccm_rv64i_zvkned_initkey, + ossl_ccm_generic_setiv, + ossl_ccm_generic_setaad, + ossl_ccm_generic_auth_encrypt, + ossl_ccm_generic_auth_decrypt, + ossl_ccm_generic_gettag +}; + const PROV_CCM_HW *ossl_prov_aes_hw_ccm(size_t keybits) { - return RISCV_HAS_ZKND_AND_ZKNE() ? &rv64i_zknd_zkne_ccm : &aes_ccm; + if (RISCV_HAS_ZVKNED() && riscv_vlen() >= 128) + return &rv64i_zvkned_ccm; + else if (RISCV_HAS_ZKND_AND_ZKNE()) + return &rv64i_zknd_zkne_ccm; + else + return &aes_ccm; } diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw.c b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw.c index 115842ccb..207a16bc7 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw.c +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw.c @@ -99,7 +99,7 @@ static int generic_aes_gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char size_t res = (16 - ctx->gcm.mres) % 16; if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, res)) - return -1; + return 0; bulk = AES_gcm_decrypt(in + res, out + res, len - res, ctx->gcm.key, diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc index bdcf67071..cc2407150 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-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 @@ -86,8 +86,13 @@ static int armv8_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx; AES_KEY *ks = &actx->ks.ks; - GCM_HW_SET_KEY_CTR_FN(ks, aes_v8_set_encrypt_key, aes_v8_encrypt, - aes_v8_ctr32_encrypt_blocks); + if (AES_UNROLL12_EOR3_CAPABLE) { + GCM_HW_SET_KEY_CTR_FN(ks, aes_v8_set_encrypt_key, aes_v8_encrypt, + aes_v8_ctr32_encrypt_blocks_unroll12_eor3); + } else { + GCM_HW_SET_KEY_CTR_FN(ks, aes_v8_set_encrypt_key, aes_v8_encrypt, + aes_v8_ctr32_encrypt_blocks); + } return 1; } diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i.inc index 7387adfde..105ca58fd 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i.inc +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i.inc @@ -8,10 +8,13 @@ */ /*- - * RISC-V 64 ZKND ZKNE support for AES GCM. + * RISC-V 64 support for AES GCM. * This file is included by cipher_aes_gcm_hw.c */ +/*- + * RISC-V 64 ZKND and ZKNE support for AES GCM. + */ static int rv64i_zknd_zkne_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, size_t keylen) { @@ -31,10 +34,85 @@ static const PROV_GCM_HW rv64i_zknd_zkne_gcm = { ossl_gcm_one_shot }; -const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) +/*- + * RISC-V RV64 ZVKNED support for AES GCM. + */ +static int rv64i_zvkned_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, + size_t keylen) { - if (RISCV_HAS_ZKND_AND_ZKNE()) - return &rv64i_zknd_zkne_gcm; - else - return &aes_gcm; + PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx; + AES_KEY *ks = &actx->ks.ks; + + /* + * Zvkned only supports 128 and 256 bit keys for key schedule generation. + * For AES-192 case, we could fallback to `AES_set_encrypt_key`. + */ + if (keylen * 8 == 128 || keylen * 8 == 256) { + GCM_HW_SET_KEY_CTR_FN(ks, rv64i_zvkned_set_encrypt_key, + rv64i_zvkned_encrypt, NULL); + } else { + GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, + rv64i_zvkned_encrypt, NULL); + } + + return 1; +} + +static const PROV_GCM_HW rv64i_zvkned_gcm = { + rv64i_zvkned_gcm_initkey, + ossl_gcm_setiv, + ossl_gcm_aad_update, + generic_aes_gcm_cipher_update, + ossl_gcm_cipher_final, + ossl_gcm_one_shot +}; + +/*- + * RISC-V RV64 ZVKB, ZVKG and ZVKNED support for AES GCM. + */ +static int rv64i_zvkb_zvkg_zvkned_gcm_initkey(PROV_GCM_CTX *ctx, + const unsigned char *key, + size_t keylen) { + PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx; + AES_KEY *ks = &actx->ks.ks; + + /* + * Zvkned only supports 128 and 256 bit keys for key schedule generation. + * For AES-192 case, we could fallback to `AES_set_encrypt_key`. + */ + if (keylen * 8 == 128 || keylen * 8 == 256) { + GCM_HW_SET_KEY_CTR_FN(ks, rv64i_zvkned_set_encrypt_key, + rv64i_zvkned_encrypt, + rv64i_zvkb_zvkned_ctr32_encrypt_blocks); + } else { + GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, + rv64i_zvkned_encrypt, + rv64i_zvkb_zvkned_ctr32_encrypt_blocks); + } + + return 1; +} + +static const PROV_GCM_HW rv64i_zvkb_zvkg_zvkned_gcm = { + rv64i_zvkb_zvkg_zvkned_gcm_initkey, + ossl_gcm_setiv, + ossl_gcm_aad_update, + generic_aes_gcm_cipher_update, + ossl_gcm_cipher_final, + ossl_gcm_one_shot +}; + +const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) { + if (RISCV_HAS_ZVKNED()) { + if (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKG() && riscv_vlen() >= 128) { + return &rv64i_zvkb_zvkg_zvkned_gcm; + } + return &rv64i_zvkned_gcm; + } + + if (RISCV_HAS_ZKND_AND_ZKNE()) { + return &rv64i_zknd_zkne_gcm; + } + + return &aes_gcm; } diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc index 94cf07df1..c892c0754 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc @@ -1,5 +1,5 @@ /* - * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2021, Intel Corporation. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw.c b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw.c index cbb5fd20f..a3b72d9f7 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw.c +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw.c @@ -146,6 +146,8 @@ const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_##mode(size_t keybits) \ # include "cipher_aes_hw_rv64i.inc" #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32 # include "cipher_aes_hw_rv32i.inc" +#elif defined (ARMv8_HWAES_CAPABLE) +# include "cipher_aes_hw_armv8.inc" #else /* The generic case */ # define PROV_CIPHER_HW_declare(mode) diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw_armv8.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw_armv8.inc new file mode 100644 index 000000000..3f73c7929 --- /dev/null +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw_armv8.inc @@ -0,0 +1,34 @@ +/* + * 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 + */ + +/* + * Crypto extension support for AES modes ecb, cbc, ofb, cfb, ctr. + * This file is included by cipher_aes_hw.c + */ + +static int cipher_hw_aes_arm_initkey(PROV_CIPHER_CTX *dat, + const unsigned char *key, + size_t keylen) +{ + int ret = cipher_hw_aes_initkey(dat, key, keylen); + if (AES_UNROLL12_EOR3_CAPABLE && dat->mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks_unroll12_eor3; + + return ret; +} + +#define PROV_CIPHER_HW_declare(mode) \ +static const PROV_CIPHER_HW aes_arm_##mode = { \ + cipher_hw_aes_arm_initkey, \ + ossl_cipher_hw_generic_##mode, \ + cipher_hw_aes_copyctx \ +}; +#define PROV_CIPHER_HW_select(mode) \ +if (ARMv8_HWAES_CAPABLE) \ + return &aes_arm_##mode; diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw_rv64i.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw_rv64i.inc index 7ebf52f97..07d479303 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw_rv64i.inc +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_hw_rv64i.inc @@ -48,12 +48,88 @@ static int cipher_hw_rv64i_zknd_zkne_initkey(PROV_CIPHER_CTX *dat, return 1; } +/*- + * RISC-V RV64 ZVKNED support for AES modes ecb, cbc, ofb, cfb, ctr. + * This file is included by cipher_aes_hw.c + */ + +#define cipher_hw_rv64i_zvkned_cbc ossl_cipher_hw_generic_cbc +#define cipher_hw_rv64i_zvkned_ecb ossl_cipher_hw_generic_ecb +#define cipher_hw_rv64i_zvkned_ofb128 ossl_cipher_hw_generic_ofb128 +#define cipher_hw_rv64i_zvkned_cfb128 ossl_cipher_hw_generic_cfb128 +#define cipher_hw_rv64i_zvkned_cfb8 ossl_cipher_hw_generic_cfb8 +#define cipher_hw_rv64i_zvkned_cfb1 ossl_cipher_hw_generic_cfb1 +#define cipher_hw_rv64i_zvkned_ctr ossl_cipher_hw_generic_ctr + +static int cipher_hw_rv64i_zvkned_initkey(PROV_CIPHER_CTX *dat, + const unsigned char *key, + size_t keylen) +{ + int ret; + PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; + AES_KEY *ks = &adat->ks.ks; + + dat->ks = ks; + + /* + * Zvkned only supports 128 and 256 bit keys for key schedule generation. + * For AES-192 case, we could fallback to `AES_set_encrypt_key`. + * All Zvkned-based implementations use the same `encrypt-key` scheduling + * for both encryption and decryption. + */ + if (keylen * 8 == 128 || keylen * 8 == 256) { + ret = rv64i_zvkned_set_encrypt_key(key, keylen * 8, ks); + } else { + ret = AES_set_encrypt_key(key, keylen * 8, ks); + } + + if (dat->mode == EVP_CIPH_CBC_MODE) { + if (dat->enc) { + dat->stream.cbc = (cbc128_f) rv64i_zvkned_cbc_encrypt; + } else { + dat->stream.cbc = (cbc128_f) rv64i_zvkned_cbc_decrypt; + } + } else if (dat->mode == EVP_CIPH_CTR_MODE) { + if (RISCV_HAS_ZVKB()) { + dat->stream.ctr = (ctr128_f) rv64i_zvkb_zvkned_ctr32_encrypt_blocks; + } + } else if (dat->mode == EVP_CIPH_ECB_MODE) { + if (dat->enc) { + dat->stream.ecb = (ecb128_f) rv64i_zvkned_ecb_encrypt; + } else { + dat->stream.ecb = (ecb128_f) rv64i_zvkned_ecb_decrypt; + } + } + + /* Zvkned supports aes-128/192/256 encryption and decryption. */ + if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE) && + !dat->enc) { + dat->block = (block128_f) rv64i_zvkned_decrypt; + } else { + dat->block = (block128_f) rv64i_zvkned_encrypt; + } + + if (ret < 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + #define PROV_CIPHER_HW_declare(mode) \ static const PROV_CIPHER_HW rv64i_zknd_zkne_##mode = { \ cipher_hw_rv64i_zknd_zkne_initkey, \ cipher_hw_rv64i_zknd_zkne_##mode, \ cipher_hw_aes_copyctx \ +}; \ +static const PROV_CIPHER_HW rv64i_zvkned_##mode = { \ + cipher_hw_rv64i_zvkned_initkey, \ + cipher_hw_rv64i_zvkned_##mode, \ + cipher_hw_aes_copyctx \ }; #define PROV_CIPHER_HW_select(mode) \ -if (RISCV_HAS_ZKND_AND_ZKNE()) \ +if (RISCV_HAS_ZVKNED() && riscv_vlen() >= 128) \ + return &rv64i_zvkned_##mode; \ +else if (RISCV_HAS_ZKND_AND_ZKNE()) \ return &rv64i_zknd_zkne_##mode; diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_ocb_hw.c b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_ocb_hw.c index f94dfdc6e..00920408b 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_ocb_hw.c +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_ocb_hw.c @@ -117,13 +117,39 @@ static int cipher_hw_aes_ocb_rv64i_zknd_zkne_initkey(PROV_CIPHER_CTX *vctx, return 1; } +static int cipher_hw_aes_ocb_rv64i_zvkned_initkey(PROV_CIPHER_CTX *vctx, + const unsigned char *key, + size_t keylen) +{ + PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx; + + /* Zvkned only supports 128 and 256 bit keys. */ + if (keylen * 8 == 128 || keylen * 8 == 256) { + OCB_SET_KEY_FN(rv64i_zvkned_set_encrypt_key, + rv64i_zvkned_set_decrypt_key, + rv64i_zvkned_encrypt, rv64i_zvkned_decrypt, + NULL, NULL); + } else { + OCB_SET_KEY_FN(AES_set_encrypt_key, AES_set_encrypt_key, + rv64i_zvkned_encrypt, rv64i_zvkned_decrypt, + NULL, NULL); + } + return 1; +} + # define PROV_CIPHER_HW_declare() \ static const PROV_CIPHER_HW aes_rv64i_zknd_zkne_ocb = { \ cipher_hw_aes_ocb_rv64i_zknd_zkne_initkey, \ NULL \ +}; \ +static const PROV_CIPHER_HW aes_rv64i_zvkned_ocb = { \ + cipher_hw_aes_ocb_rv64i_zvkned_initkey, \ + NULL \ }; # define PROV_CIPHER_HW_select() \ - if (RISCV_HAS_ZKND_AND_ZKNE()) \ + if (RISCV_HAS_ZVKNED() && riscv_vlen() >= 128) \ + return &aes_rv64i_zvkned_ocb; \ + else if (RISCV_HAS_ZKND_AND_ZKNE()) \ return &aes_rv64i_zknd_zkne_ocb; #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32 diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_xts_hw.c b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_xts_hw.c index 87cb550ae..3163234c3 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_aes_xts_hw.c +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_aes_xts_hw.c @@ -175,14 +175,74 @@ static int cipher_hw_aes_xts_rv64i_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx, return 1; } +static int cipher_hw_aes_xts_rv64i_zvbb_zvkg_zvkned_initkey( + PROV_CIPHER_CTX *ctx, const unsigned char *key, size_t keylen) +{ + PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; + OSSL_xts_stream_fn stream_enc = NULL; + OSSL_xts_stream_fn stream_dec = NULL; + + /* Zvkned only supports 128 and 256 bit keys. */ + if (keylen * 8 == 128 * 2 || keylen * 8 == 256 * 2) { + XTS_SET_KEY_FN(rv64i_zvkned_set_encrypt_key, + rv64i_zvkned_set_decrypt_key, rv64i_zvkned_encrypt, + rv64i_zvkned_decrypt, + rv64i_zvbb_zvkg_zvkned_aes_xts_encrypt, + rv64i_zvbb_zvkg_zvkned_aes_xts_decrypt); + } else { + XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_encrypt_key, + rv64i_zvkned_encrypt, rv64i_zvkned_decrypt, + stream_enc, stream_dec); + } + return 1; +} + +static int cipher_hw_aes_xts_rv64i_zvkned_initkey(PROV_CIPHER_CTX *ctx, + const unsigned char *key, + size_t keylen) +{ + PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; + OSSL_xts_stream_fn stream_enc = NULL; + OSSL_xts_stream_fn stream_dec = NULL; + + /* Zvkned only supports 128 and 256 bit keys. */ + if (keylen * 8 == 128 * 2 || keylen * 8 == 256 * 2) { + XTS_SET_KEY_FN(rv64i_zvkned_set_encrypt_key, + rv64i_zvkned_set_decrypt_key, + rv64i_zvkned_encrypt, rv64i_zvkned_decrypt, + stream_enc, stream_dec); + } else { + XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_encrypt_key, + rv64i_zvkned_encrypt, rv64i_zvkned_decrypt, + stream_enc, stream_dec); + } + return 1; +} + # define PROV_CIPHER_HW_declare_xts() \ static const PROV_CIPHER_HW aes_xts_rv64i_zknd_zkne = { \ cipher_hw_aes_xts_rv64i_zknd_zkne_initkey, \ NULL, \ cipher_hw_aes_xts_copyctx \ +}; \ +static const PROV_CIPHER_HW aes_xts_rv64i_zvkned = { \ + cipher_hw_aes_xts_rv64i_zvkned_initkey, \ + NULL, \ + cipher_hw_aes_xts_copyctx \ +}; \ +static const PROV_CIPHER_HW aes_xts_rv64i_zvbb_zvkg_zvkned = { \ + cipher_hw_aes_xts_rv64i_zvbb_zvkg_zvkned_initkey, \ + NULL, \ + cipher_hw_aes_xts_copyctx \ }; + # define PROV_CIPHER_HW_select_xts() \ -if (RISCV_HAS_ZKND_AND_ZKNE()) \ +if (RISCV_HAS_ZVBB() && RISCV_HAS_ZVKG() && RISCV_HAS_ZVKNED() && \ + riscv_vlen() >= 128) \ + return &aes_xts_rv64i_zvbb_zvkg_zvkned; \ +if (RISCV_HAS_ZVKNED() && riscv_vlen() >= 128) \ + return &aes_xts_rv64i_zvkned; \ +else if (RISCV_HAS_ZKND_AND_ZKNE()) \ return &aes_xts_rv64i_zknd_zkne; #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32 diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm.h b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm.h index 189e71e9e..561437993 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm.h +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm.h @@ -10,6 +10,7 @@ #include "crypto/sm4.h" #include "prov/ciphercommon.h" #include "prov/ciphercommon_ccm.h" +#include "crypto/sm4_platform.h" typedef struct prov_sm4_ccm_ctx_st { PROV_CCM_CTX base; /* Must be first */ diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm_hw.c b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm_hw.c index 537024b09..34f0e751e 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm_hw.c +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm_hw.c @@ -59,7 +59,11 @@ static const PROV_CCM_HW ccm_sm4 = { ossl_ccm_generic_gettag }; +#if defined(__riscv) && __riscv_xlen == 64 +# include "cipher_sm4_ccm_hw_rv64i.inc" +#else const PROV_CCM_HW *ossl_prov_sm4_hw_ccm(size_t keybits) { return &ccm_sm4; } +#endif diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm_hw_rv64i.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm_hw_rv64i.inc new file mode 100644 index 000000000..c20c9f688 --- /dev/null +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_ccm_hw_rv64i.inc @@ -0,0 +1,41 @@ +/* + * 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 + */ + +/*- + * RV64I ZVKSED support for SM4 CCM. + * This file is included by cipher_sm4_ccm_hw.c + */ + +static int rv64i_zvksed_sm4_ccm_initkey(PROV_CCM_CTX *ctx, + const unsigned char *key, + size_t keylen) +{ + PROV_SM4_CCM_CTX *actx = (PROV_SM4_CCM_CTX *)ctx; + + SM4_HW_CCM_SET_KEY_FN(rv64i_zvksed_sm4_set_encrypt_key, + rv64i_zvksed_sm4_encrypt, NULL, NULL); + return 1; +} + +static const PROV_CCM_HW rv64i_zvksed_sm4_ccm = { + rv64i_zvksed_sm4_ccm_initkey, + ossl_ccm_generic_setiv, + ossl_ccm_generic_setaad, + ossl_ccm_generic_auth_encrypt, + ossl_ccm_generic_auth_decrypt, + ossl_ccm_generic_gettag +}; + +const PROV_CCM_HW *ossl_prov_sm4_hw_ccm(size_t keybits) +{ + if (RISCV_HAS_ZVKB_AND_ZVKSED() && riscv_vlen() >= 128) + return &rv64i_zvksed_sm4_ccm; + else + return &ccm_sm4; +} diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_gcm_hw.c b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_gcm_hw.c index 630d8a321..06ca45078 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_gcm_hw.c +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_gcm_hw.c @@ -89,7 +89,11 @@ static const PROV_GCM_HW sm4_gcm = { ossl_gcm_one_shot }; +#if defined(__riscv) && __riscv_xlen == 64 +# include "cipher_sm4_gcm_hw_rv64i.inc" +#else const PROV_GCM_HW *ossl_prov_sm4_hw_gcm(size_t keybits) { return &sm4_gcm; } +#endif diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_gcm_hw_rv64i.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_gcm_hw_rv64i.inc new file mode 100644 index 000000000..109d13b43 --- /dev/null +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_gcm_hw_rv64i.inc @@ -0,0 +1,42 @@ +/* + * 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 + */ + +/*- + * RISC-V 64 ZVKSED support for SM4 GCM. + * This file is included by cipher_sm4_gcm_hw.c + */ + +static int rv64i_zvksed_sm4_gcm_initkey(PROV_GCM_CTX *ctx, + const unsigned char *key, + size_t keylen) +{ + PROV_SM4_GCM_CTX *actx = (PROV_SM4_GCM_CTX *)ctx; + SM4_KEY *ks = &actx->ks.ks; + + SM4_GCM_HW_SET_KEY_CTR_FN(ks, rv64i_zvksed_sm4_set_encrypt_key, + rv64i_zvksed_sm4_encrypt, NULL); + return 1; +} + +static const PROV_GCM_HW rv64i_zvksed_sm4_gcm = { + rv64i_zvksed_sm4_gcm_initkey, + ossl_gcm_setiv, + ossl_gcm_aad_update, + hw_gcm_cipher_update, + ossl_gcm_cipher_final, + ossl_gcm_one_shot +}; + +const PROV_GCM_HW *ossl_prov_sm4_hw_gcm(size_t keybits) +{ + if (RISCV_HAS_ZVKB_AND_ZVKSED() && riscv_vlen() >= 128) + return &rv64i_zvksed_sm4_gcm; + else + return &sm4_gcm; +} diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_hw.c b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_hw.c index 7419744a4..c4f2f97cc 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_hw.c +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_hw.c @@ -127,11 +127,21 @@ static const PROV_CIPHER_HW sm4_##mode = { \ ossl_cipher_hw_generic_##mode, \ cipher_hw_sm4_copyctx \ }; \ +PROV_CIPHER_HW_declare(mode) \ const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_##mode(size_t keybits) \ { \ + PROV_CIPHER_HW_select(mode) \ return &sm4_##mode; \ } +#if defined(__riscv) && __riscv_xlen == 64 +# include "cipher_sm4_hw_rv64i.inc" +#else +/* The generic case */ +# define PROV_CIPHER_HW_declare(mode) +# define PROV_CIPHER_HW_select(mode) +#endif + PROV_CIPHER_HW_sm4_mode(cbc) PROV_CIPHER_HW_sm4_mode(ecb) PROV_CIPHER_HW_sm4_mode(ofb128) diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_hw_rv64i.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_hw_rv64i.inc new file mode 100644 index 000000000..763d9d09d --- /dev/null +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_hw_rv64i.inc @@ -0,0 +1,52 @@ +/* + * 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 + */ + +/*- + * RV64 ZVKSED support for AES modes ecb, cbc, ofb, cfb, ctr. + * This file is included by cipher_sm4_hw.c + */ + +#define cipher_hw_rv64i_zvksed_sm4_cbc ossl_cipher_hw_generic_cbc +#define cipher_hw_rv64i_zvksed_sm4_ecb ossl_cipher_hw_generic_ecb +#define cipher_hw_rv64i_zvksed_sm4_ofb128 ossl_cipher_hw_generic_ofb128 +#define cipher_hw_rv64i_zvksed_sm4_cfb128 ossl_cipher_hw_generic_cfb128 +#define cipher_hw_rv64i_zvksed_sm4_ctr ossl_cipher_hw_generic_ctr + +static int cipher_hw_rv64i_zvksed_sm4_initkey(PROV_CIPHER_CTX *ctx, + const unsigned char *key, + size_t keylen) +{ + PROV_SM4_CTX *sctx = (PROV_SM4_CTX *)ctx; + SM4_KEY *ks = &sctx->ks.ks; + + ctx->ks = ks; + if (ctx->enc + || (ctx->mode != EVP_CIPH_ECB_MODE + && ctx->mode != EVP_CIPH_CBC_MODE)) { + rv64i_zvksed_sm4_set_encrypt_key(key, ks); + ctx->block = (block128_f) rv64i_zvksed_sm4_encrypt; + ctx->stream.cbc = NULL; + } else { + rv64i_zvksed_sm4_set_decrypt_key(key, ks); + ctx->block = (block128_f) rv64i_zvksed_sm4_decrypt; + ctx->stream.cbc = NULL; + } + + return 1; +} + +#define PROV_CIPHER_HW_declare(mode) \ +static const PROV_CIPHER_HW rv64i_zvksed_sm4_##mode = { \ + cipher_hw_rv64i_zvksed_sm4_initkey, \ + cipher_hw_rv64i_zvksed_sm4_##mode, \ + cipher_hw_sm4_copyctx \ +}; +#define PROV_CIPHER_HW_select(mode) \ +if (RISCV_HAS_ZVKB_AND_ZVKSED() && riscv_vlen() >= 128) \ + return &rv64i_zvksed_sm4_##mode; diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_xts_hw.c b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_xts_hw.c index 44af243a6..6cf58e851 100644 --- a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_xts_hw.c +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_xts_hw.c @@ -88,7 +88,12 @@ static const PROV_CIPHER_HW sm4_generic_xts = { NULL, cipher_hw_sm4_xts_copyctx }; + +#if defined(__riscv) && __riscv_xlen == 64 +# include "cipher_sm4_xts_hw_rv64i.inc" +#else const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_xts(size_t keybits) { return &sm4_generic_xts; } +#endif diff --git a/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_xts_hw_rv64i.inc b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_xts_hw_rv64i.inc new file mode 100644 index 000000000..2ab15269c --- /dev/null +++ b/libs/openssl-3/providers/implementations/ciphers/cipher_sm4_xts_hw_rv64i.inc @@ -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 + */ + +/*- + * RISC-V 64 ZVKSED support for SM4 GCM. + * This file is included by cipher_sm4_gcm_hw.c + */ + +static int rv64i_zvksed_sm4_xts_initkey(PROV_CIPHER_CTX *ctx, + const unsigned char *key, + size_t keylen) +{ + PROV_SM4_XTS_CTX *xctx = (PROV_SM4_XTS_CTX *)ctx; + OSSL_xts_stream_fn stream_fn = NULL; + OSSL_xts_stream_fn stream_gb_fn = NULL; + + XTS_SET_KEY_FN(rv64i_zvksed_sm4_set_encrypt_key, + rv64i_zvksed_sm4_set_decrypt_key, + rv64i_zvksed_sm4_encrypt, + rv64i_zvksed_sm4_decrypt, + stream_fn, stream_gb_fn); + return 1; +} + +static const PROV_CIPHER_HW rv64i_zvksed_sm4_xts = { + rv64i_zvksed_sm4_xts_initkey, + NULL, + cipher_hw_sm4_xts_copyctx +}; + +const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_xts(size_t keybits) +{ + if (RISCV_HAS_ZVKB_AND_ZVKSED() && riscv_vlen() >= 128) + return &rv64i_zvksed_sm4_xts; + else + return &sm4_generic_xts; +} diff --git a/libs/openssl-3/providers/implementations/ciphers/ciphercommon.c b/libs/openssl-3/providers/implementations/ciphers/ciphercommon.c index db81af540..7ad3eb0a1 100644 --- a/libs/openssl-3/providers/implementations/ciphers/ciphercommon.c +++ b/libs/openssl-3/providers/implementations/ciphers/ciphercommon.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 diff --git a/libs/openssl-3/providers/implementations/ciphers/ciphercommon_ccm.c b/libs/openssl-3/providers/implementations/ciphers/ciphercommon_ccm.c index e638eb163..33105911e 100644 --- a/libs/openssl-3/providers/implementations/ciphers/ciphercommon_ccm.c +++ b/libs/openssl-3/providers/implementations/ciphers/ciphercommon_ccm.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 diff --git a/libs/openssl-3/providers/implementations/digests/blake2_prov.c b/libs/openssl-3/providers/implementations/digests/blake2_prov.c index d31627b92..37c3e7038 100644 --- a/libs/openssl-3/providers/implementations/digests/blake2_prov.c +++ b/libs/openssl-3/providers/implementations/digests/blake2_prov.c @@ -8,123 +8,181 @@ */ #include +#include #include +#include #include "prov/blake2.h" #include "prov/digestcommon.h" #include "prov/implementations.h" -static int ossl_blake2s256_init(void *ctx) -{ - BLAKE2S_PARAM P; - - ossl_blake2s_param_init(&P); - return ossl_blake2s_init((BLAKE2S_CTX *)ctx, &P); -} - -static int ossl_blake2b512_init(void *ctx) -{ - struct blake2b_md_data_st *mdctx = ctx; - uint8_t digest_length = mdctx->params.digest_length; - - ossl_blake2b_param_init(&mdctx->params); - if (digest_length != 0) - mdctx->params.digest_length = digest_length; - return ossl_blake2b_init(&mdctx->ctx, &mdctx->params); -} - -/* ossl_blake2s256_functions */ -IMPLEMENT_digest_functions(blake2s256, BLAKE2S_CTX, - BLAKE2S_BLOCKBYTES, BLAKE2S_DIGEST_LENGTH, 0, - ossl_blake2s256_init, ossl_blake2s_update, - ossl_blake2s_final) - -/* ossl_blake2b512_functions */ - -static OSSL_FUNC_digest_init_fn blake2b512_internal_init; -static OSSL_FUNC_digest_newctx_fn blake2b512_newctx; -static OSSL_FUNC_digest_freectx_fn blake2b512_freectx; -static OSSL_FUNC_digest_dupctx_fn blake2b512_dupctx; -static OSSL_FUNC_digest_final_fn blake2b512_internal_final; -static OSSL_FUNC_digest_get_params_fn blake2b512_get_params; - -static int blake2b512_internal_init(void *ctx, const OSSL_PARAM params[]) -{ - return ossl_prov_is_running() && ossl_blake2b_set_ctx_params(ctx, params) - && ossl_blake2b512_init(ctx); -} - -static void *blake2b512_newctx(void *prov_ctx) -{ - struct blake2b_md_data_st *ctx; - - ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) : NULL; - return ctx; -} - -static void blake2b512_freectx(void *vctx) -{ - struct blake2b_md_data_st *ctx; - - ctx = (struct blake2b_md_data_st *)vctx; - OPENSSL_clear_free(ctx, sizeof(*ctx)); -} - -static void *blake2b512_dupctx(void *ctx) -{ - struct blake2b_md_data_st *in, *ret; - - in = (struct blake2b_md_data_st *)ctx; - ret = ossl_prov_is_running()? OPENSSL_malloc(sizeof(*ret)) : NULL; - if (ret != NULL) - *ret = *in; - return ret; -} - -static int blake2b512_internal_final(void *ctx, unsigned char *out, - size_t *outl, size_t outsz) -{ - struct blake2b_md_data_st *b_ctx; - - b_ctx = (struct blake2b_md_data_st *)ctx; - - if (!ossl_prov_is_running()) - return 0; - - *outl = b_ctx->ctx.outlen; - - if (outsz == 0) - return 1; - - if (outsz < *outl) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE); - return 0; - } - - return ossl_blake2b_final(out, ctx); -} - -static int blake2b512_get_params(OSSL_PARAM params[]) -{ - return ossl_digest_default_get_params(params, BLAKE2B_BLOCKBYTES, 64, 0); -} - -const OSSL_DISPATCH ossl_blake2b512_functions[] = { - {OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))blake2b512_newctx}, - {OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))ossl_blake2b_update}, - {OSSL_FUNC_DIGEST_FINAL, (void (*)(void))blake2b512_internal_final}, - {OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))blake2b512_freectx}, - {OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))blake2b512_dupctx}, - {OSSL_FUNC_DIGEST_GET_PARAMS, (void (*)(void))blake2b512_get_params}, - {OSSL_FUNC_DIGEST_GETTABLE_PARAMS, - (void (*)(void))ossl_digest_default_gettable_params}, - {OSSL_FUNC_DIGEST_INIT, (void (*)(void))blake2b512_internal_init}, - {OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, - (void (*)(void))ossl_blake2b_gettable_ctx_params}, - {OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, - (void (*)(void))ossl_blake2b_settable_ctx_params}, - {OSSL_FUNC_DIGEST_GET_CTX_PARAMS, - (void (*)(void))ossl_blake2b_get_ctx_params}, - {OSSL_FUNC_DIGEST_SET_CTX_PARAMS, - (void (*)(void))ossl_blake2b_set_ctx_params}, - {0, NULL} +#define IMPLEMENT_BLAKE_functions(variant, VARIANT, variantsize) \ +static const OSSL_PARAM known_blake##variant##_ctx_params[] = { \ + {OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, \ + OSSL_PARAM_END \ +}; \ + \ +const OSSL_PARAM *ossl_blake##variant##_gettable_ctx_params(ossl_unused void *ctx, \ + ossl_unused void *pctx) \ +{ \ + return known_blake##variant##_ctx_params; \ +} \ + \ +const OSSL_PARAM *ossl_blake##variant##_settable_ctx_params(ossl_unused void *ctx, \ + ossl_unused void *pctx) \ +{ \ + return known_blake##variant##_ctx_params; \ +} \ + \ +int ossl_blake##variant##_get_ctx_params(void *vctx, OSSL_PARAM params[]) \ +{ \ + struct blake##variant##_md_data_st *mdctx = vctx; \ + OSSL_PARAM *p; \ + \ + BLAKE##VARIANT##_CTX *ctx = &mdctx->ctx; \ + \ + if (ctx == NULL) \ + return 0; \ + if (params == NULL) \ + return 1; \ + \ + p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE); \ + if (p != NULL \ + && !OSSL_PARAM_set_uint(p, (unsigned int)mdctx->params.digest_length)) { \ + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); \ + return 0; \ + } \ + \ + return 1; \ +} \ + \ +int ossl_blake##variant##_set_ctx_params(void *vctx, const OSSL_PARAM params[]) \ +{ \ + size_t size; \ + struct blake##variant##_md_data_st *mdctx = vctx; \ + const OSSL_PARAM *p; \ + \ + BLAKE##VARIANT##_CTX *ctx = &mdctx->ctx; \ + \ + if (ctx == NULL) \ + return 0; \ + if (params == NULL) \ + return 1; \ + \ + p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE); \ + if (p != NULL) { \ + if (!OSSL_PARAM_get_size_t(p, &size)) { \ + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); \ + return 0; \ + } \ + if (size < 1 || size > BLAKE##VARIANT##_OUTBYTES) { \ + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE); \ + return 0; \ + } \ + ossl_blake##variant##_param_set_digest_length(&mdctx->params, (uint8_t)size); \ + } \ + \ + return 1; \ +} \ + \ +static int ossl_blake##variantsize##_init(void *ctx) \ +{ \ + struct blake##variant##_md_data_st *mdctx = ctx; \ + uint8_t digest_length = mdctx->params.digest_length; \ + \ + ossl_blake##variant##_param_init(&mdctx->params); \ + if (digest_length != 0) \ + mdctx->params.digest_length = digest_length; \ + return ossl_blake##variant##_init(&mdctx->ctx, &mdctx->params); \ +} \ + \ +static OSSL_FUNC_digest_init_fn blake##variantsize##_internal_init; \ +static OSSL_FUNC_digest_newctx_fn blake##variantsize##_newctx; \ +static OSSL_FUNC_digest_freectx_fn blake##variantsize##_freectx; \ +static OSSL_FUNC_digest_dupctx_fn blake##variantsize##_dupctx; \ +static OSSL_FUNC_digest_final_fn blake##variantsize##_internal_final; \ +static OSSL_FUNC_digest_get_params_fn blake##variantsize##_get_params; \ + \ +static int blake##variantsize##_internal_init(void *ctx, const OSSL_PARAM params[]) \ +{ \ + return ossl_prov_is_running() && ossl_blake##variant##_set_ctx_params(ctx, params) \ + && ossl_blake##variantsize##_init(ctx); \ +} \ + \ +static void *blake##variantsize##_newctx(void *prov_ctx) \ +{ \ + struct blake##variant##_md_data_st *ctx; \ + \ + ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) : NULL; \ + return ctx; \ +} \ + \ +static void blake##variantsize##_freectx(void *vctx) \ +{ \ + struct blake##variant##_md_data_st *ctx; \ + \ + ctx = (struct blake##variant##_md_data_st *)vctx; \ + OPENSSL_clear_free(ctx, sizeof(*ctx)); \ +} \ + \ +static void *blake##variantsize##_dupctx(void *ctx) \ +{ \ + struct blake##variant##_md_data_st *in, *ret; \ + \ + in = (struct blake##variant##_md_data_st *)ctx; \ + ret = ossl_prov_is_running()? OPENSSL_malloc(sizeof(*ret)) : NULL; \ + if (ret != NULL) \ + *ret = *in; \ + return ret; \ +} \ + \ +static int blake##variantsize##_internal_final(void *ctx, unsigned char *out, \ + size_t *outl, size_t outsz) \ +{ \ + struct blake##variant##_md_data_st *b_ctx; \ + \ + b_ctx = (struct blake##variant##_md_data_st *)ctx; \ + \ + if (!ossl_prov_is_running()) \ + return 0; \ + \ + *outl = b_ctx->ctx.outlen; \ + \ + if (outsz == 0) \ + return 1; \ + \ + if (outsz < *outl) { \ + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE); \ + return 0; \ + } \ + \ + return ossl_blake##variant##_final(out, ctx); \ +} \ + \ +static int blake##variantsize##_get_params(OSSL_PARAM params[]) \ +{ \ + return ossl_digest_default_get_params(params, BLAKE##VARIANT##_BLOCKBYTES, BLAKE##VARIANT##_OUTBYTES, 0); \ +} \ + \ +const OSSL_DISPATCH ossl_blake##variantsize##_functions[] = { \ + {OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))blake##variantsize##_newctx}, \ + {OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))ossl_blake##variant##_update}, \ + {OSSL_FUNC_DIGEST_FINAL, (void (*)(void))blake##variantsize##_internal_final}, \ + {OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))blake##variantsize##_freectx}, \ + {OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))blake##variantsize##_dupctx}, \ + {OSSL_FUNC_DIGEST_GET_PARAMS, (void (*)(void))blake##variantsize##_get_params}, \ + {OSSL_FUNC_DIGEST_GETTABLE_PARAMS, \ + (void (*)(void))ossl_digest_default_gettable_params}, \ + {OSSL_FUNC_DIGEST_INIT, (void (*)(void))blake##variantsize##_internal_init}, \ + {OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, \ + (void (*)(void))ossl_blake##variant##_gettable_ctx_params}, \ + {OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, \ + (void (*)(void))ossl_blake##variant##_settable_ctx_params}, \ + {OSSL_FUNC_DIGEST_GET_CTX_PARAMS, \ + (void (*)(void))ossl_blake##variant##_get_ctx_params}, \ + {OSSL_FUNC_DIGEST_SET_CTX_PARAMS, \ + (void (*)(void))ossl_blake##variant##_set_ctx_params}, \ + {0, NULL} \ }; + +IMPLEMENT_BLAKE_functions(2s, 2S, 2s256) +IMPLEMENT_BLAKE_functions(2b, 2B, 2b512) diff --git a/libs/openssl-3/providers/implementations/digests/blake2b_prov.c b/libs/openssl-3/providers/implementations/digests/blake2b_prov.c index 95df0d4a2..6ef7fac00 100644 --- a/libs/openssl-3/providers/implementations/digests/blake2b_prov.c +++ b/libs/openssl-3/providers/implementations/digests/blake2b_prov.c @@ -17,81 +17,10 @@ #include #include #include -#include -#include -#include #include "internal/numbers.h" #include "blake2_impl.h" #include "prov/blake2.h" -static const OSSL_PARAM known_blake2b_ctx_params[] = { - {OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, - OSSL_PARAM_END -}; - -const OSSL_PARAM *ossl_blake2b_gettable_ctx_params(ossl_unused void *ctx, - ossl_unused void *pctx) -{ - return known_blake2b_ctx_params; -} - -const OSSL_PARAM *ossl_blake2b_settable_ctx_params(ossl_unused void *ctx, - ossl_unused void *pctx) -{ - return known_blake2b_ctx_params; -} - -int ossl_blake2b_get_ctx_params(void *vctx, OSSL_PARAM params[]) -{ - struct blake2b_md_data_st *mdctx = vctx; - OSSL_PARAM *p; - - BLAKE2B_CTX *ctx = &mdctx->ctx; - - if (ctx == NULL) - return 0; - if (params == NULL) - return 1; - - p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE); - if (p != NULL - && !OSSL_PARAM_set_uint(p, (unsigned int)mdctx->params.digest_length)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - - return 1; -} - -int ossl_blake2b_set_ctx_params(void *vctx, const OSSL_PARAM params[]) -{ - size_t size; - struct blake2b_md_data_st *mdctx = vctx; - const OSSL_PARAM *p; - - BLAKE2B_CTX *ctx = &mdctx->ctx; - - if (ctx == NULL) - return 0; - if (params == NULL) - return 1; - - p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE); - if (p != NULL) { - if (!OSSL_PARAM_get_size_t(p, &size)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - if (size < 1 || size > BLAKE2B_OUTBYTES) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE); - return 0; - } - ossl_blake2b_param_set_digest_length(&mdctx->params, (uint8_t)size); - } - - return 1; -} - static const uint64_t blake2b_IV[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, diff --git a/libs/openssl-3/providers/implementations/digests/sha3_prov.c b/libs/openssl-3/providers/implementations/digests/sha3_prov.c index 423bed798..2fd0f928e 100644 --- a/libs/openssl-3/providers/implementations/digests/sha3_prov.c +++ b/libs/openssl-3/providers/implementations/digests/sha3_prov.c @@ -33,10 +33,12 @@ static OSSL_FUNC_digest_update_fn keccak_update; static OSSL_FUNC_digest_final_fn keccak_final; static OSSL_FUNC_digest_freectx_fn keccak_freectx; static OSSL_FUNC_digest_dupctx_fn keccak_dupctx; +static OSSL_FUNC_digest_squeeze_fn shake_squeeze; static OSSL_FUNC_digest_set_ctx_params_fn shake_set_ctx_params; static OSSL_FUNC_digest_settable_ctx_params_fn shake_settable_ctx_params; static sha3_absorb_fn generic_sha3_absorb; static sha3_final_fn generic_sha3_final; +static sha3_squeeze_fn generic_sha3_squeeze; #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM) /* @@ -103,20 +105,37 @@ static int keccak_update(void *vctx, const unsigned char *inp, size_t len) } static int keccak_final(void *vctx, unsigned char *out, size_t *outl, - size_t outsz) + size_t outlen) { int ret = 1; KECCAK1600_CTX *ctx = vctx; if (!ossl_prov_is_running()) return 0; - if (outsz > 0) - ret = ctx->meth.final(out, ctx); + if (outlen > 0) + ret = ctx->meth.final(ctx, out, ctx->md_size); *outl = ctx->md_size; return ret; } +static int shake_squeeze(void *vctx, unsigned char *out, size_t *outl, + size_t outlen) +{ + int ret = 1; + KECCAK1600_CTX *ctx = vctx; + + if (!ossl_prov_is_running()) + return 0; + if (ctx->meth.squeeze == NULL) + return 0; + if (outlen > 0) + ret = ctx->meth.squeeze(ctx, out, outlen); + + *outl = outlen; + return ret; +} + /*- * Generic software version of the absorb() and final(). */ @@ -124,18 +143,35 @@ static size_t generic_sha3_absorb(void *vctx, const void *inp, size_t len) { KECCAK1600_CTX *ctx = vctx; + if (!(ctx->xof_state == XOF_STATE_INIT || + ctx->xof_state == XOF_STATE_ABSORB)) + return 0; + ctx->xof_state = XOF_STATE_ABSORB; return SHA3_absorb(ctx->A, inp, len, ctx->block_size); } -static int generic_sha3_final(unsigned char *md, void *vctx) +static int generic_sha3_final(void *vctx, unsigned char *out, size_t outlen) { - return ossl_sha3_final(md, (KECCAK1600_CTX *)vctx); + return ossl_sha3_final((KECCAK1600_CTX *)vctx, out, outlen); +} + +static int generic_sha3_squeeze(void *vctx, unsigned char *out, size_t outlen) +{ + return ossl_sha3_squeeze((KECCAK1600_CTX *)vctx, out, outlen); } static PROV_SHA3_METHOD sha3_generic_md = { generic_sha3_absorb, - generic_sha3_final + generic_sha3_final, + NULL +}; + +static PROV_SHA3_METHOD shake_generic_md = +{ + generic_sha3_absorb, + generic_sha3_final, + generic_sha3_squeeze }; #if defined(S390_SHA3) @@ -152,89 +188,211 @@ static size_t s390x_sha3_absorb(void *vctx, const void *inp, size_t len) KECCAK1600_CTX *ctx = vctx; size_t rem = len % ctx->block_size; + if (!(ctx->xof_state == XOF_STATE_INIT || + ctx->xof_state == XOF_STATE_ABSORB)) + return 0; + ctx->xof_state = XOF_STATE_ABSORB; s390x_kimd(inp, len - rem, ctx->pad, ctx->A); return rem; } -static int s390x_sha3_final(unsigned char *md, void *vctx) +static int s390x_sha3_final(void *vctx, unsigned char *out, size_t outlen) { KECCAK1600_CTX *ctx = vctx; if (!ossl_prov_is_running()) return 0; + if (!(ctx->xof_state == XOF_STATE_INIT || + ctx->xof_state == XOF_STATE_ABSORB)) + return 0; + ctx->xof_state = XOF_STATE_FINAL; s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, ctx->pad, ctx->A); - memcpy(md, ctx->A, ctx->md_size); + memcpy(out, ctx->A, outlen); + return 1; +} + +static int s390x_shake_final(void *vctx, unsigned char *out, size_t outlen) +{ + KECCAK1600_CTX *ctx = vctx; + + if (!ossl_prov_is_running()) + return 0; + if (!(ctx->xof_state == XOF_STATE_INIT || + ctx->xof_state == XOF_STATE_ABSORB)) + return 0; + ctx->xof_state = XOF_STATE_FINAL; + s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, ctx->pad, ctx->A); return 1; } -static int s390x_shake_final(unsigned char *md, void *vctx) +static int s390x_shake_squeeze(void *vctx, unsigned char *out, size_t outlen) { KECCAK1600_CTX *ctx = vctx; + size_t len; if (!ossl_prov_is_running()) return 0; - s390x_klmd(ctx->buf, ctx->bufsz, md, ctx->md_size, ctx->pad, ctx->A); + if (ctx->xof_state == XOF_STATE_FINAL) + return 0; + /* + * On the first squeeze call, finish the absorb process (incl. padding). + */ + if (ctx->xof_state != XOF_STATE_SQUEEZE) { + ctx->xof_state = XOF_STATE_SQUEEZE; + s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, ctx->pad, ctx->A); + ctx->bufsz = outlen % ctx->block_size; + /* reuse ctx->bufsz to count bytes squeezed from current sponge */ + return 1; + } + ctx->xof_state = XOF_STATE_SQUEEZE; + if (ctx->bufsz != 0) { + len = ctx->block_size - ctx->bufsz; + if (outlen < len) + len = outlen; + memcpy(out, (char *)ctx->A + ctx->bufsz, len); + out += len; + outlen -= len; + ctx->bufsz += len; + if (ctx->bufsz == ctx->block_size) + ctx->bufsz = 0; + } + if (outlen == 0) + return 1; + s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A); + ctx->bufsz = outlen % ctx->block_size; + return 1; } -static int s390x_keccakc_final(unsigned char *md, void *vctx, int padding) +static int s390x_keccakc_final(void *vctx, unsigned char *out, size_t outlen, + int padding) { KECCAK1600_CTX *ctx = vctx; size_t bsz = ctx->block_size; size_t num = ctx->bufsz; - size_t needed = ctx->md_size; + size_t needed = outlen; if (!ossl_prov_is_running()) return 0; - if (ctx->md_size == 0) + if (!(ctx->xof_state == XOF_STATE_INIT || + ctx->xof_state == XOF_STATE_ABSORB)) + return 0; + ctx->xof_state = XOF_STATE_FINAL; + if (outlen == 0) return 1; memset(ctx->buf + num, 0, bsz - num); ctx->buf[num] = padding; ctx->buf[bsz - 1] |= 0x80; s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A); num = needed > bsz ? bsz : needed; - memcpy(md, ctx->A, num); + memcpy(out, ctx->A, num); needed -= num; if (needed > 0) - s390x_klmd(NULL, 0, md + bsz, needed, ctx->pad | S390X_KLMD_PS, ctx->A); + s390x_klmd(NULL, 0, out + bsz, needed, ctx->pad | S390X_KLMD_PS, ctx->A); + + return 1; +} + +static int s390x_keccak_final(void *vctx, unsigned char *out, size_t outlen) +{ + return s390x_keccakc_final(vctx, out, outlen, 0x01); +} + +static int s390x_kmac_final(void *vctx, unsigned char *out, size_t outlen) +{ + return s390x_keccakc_final(vctx, out, outlen, 0x04); +} + +static int s390x_keccakc_squeeze(void *vctx, unsigned char *out, size_t outlen, + int padding) +{ + KECCAK1600_CTX *ctx = vctx; + size_t len; + + if (!ossl_prov_is_running()) + return 0; + 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) { + len = ctx->block_size - ctx->bufsz; + memset(ctx->buf + ctx->bufsz, 0, len); + ctx->buf[ctx->bufsz] = padding; + ctx->buf[ctx->block_size - 1] |= 0x80; + s390x_kimd(ctx->buf, ctx->block_size, ctx->pad, ctx->A); + ctx->bufsz = 0; + /* reuse ctx->bufsz to count bytes squeezed from current sponge */ + } + if (ctx->bufsz != 0 || ctx->xof_state != XOF_STATE_SQUEEZE) { + len = ctx->block_size - ctx->bufsz; + if (outlen < len) + len = outlen; + memcpy(out, (char *)ctx->A + ctx->bufsz, len); + out += len; + outlen -= len; + ctx->bufsz += len; + if (ctx->bufsz == ctx->block_size) + ctx->bufsz = 0; + } + ctx->xof_state = XOF_STATE_SQUEEZE; + if (outlen == 0) + return 1; + s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A); + ctx->bufsz = outlen % ctx->block_size; return 1; } -static int s390x_keccak_final(unsigned char *md, void *vctx) +static int s390x_keccak_squeeze(void *vctx, unsigned char *out, size_t outlen) { - return s390x_keccakc_final(md, vctx, 0x01); + return s390x_keccakc_squeeze(vctx, out, outlen, 0x01); } -static int s390x_kmac_final(unsigned char *md, void *vctx) +static int s390x_kmac_squeeze(void *vctx, unsigned char *out, size_t outlen) { - return s390x_keccakc_final(md, vctx, 0x04); + return s390x_keccakc_squeeze(vctx, out, outlen, 0x04); } static PROV_SHA3_METHOD sha3_s390x_md = { s390x_sha3_absorb, - s390x_sha3_final + s390x_sha3_final, + NULL, }; static PROV_SHA3_METHOD keccak_s390x_md = { s390x_sha3_absorb, - s390x_keccak_final + s390x_keccak_final, + s390x_keccak_squeeze, }; static PROV_SHA3_METHOD shake_s390x_md = { s390x_sha3_absorb, - s390x_shake_final + s390x_shake_final, + s390x_shake_squeeze, }; static PROV_SHA3_METHOD kmac_s390x_md = { s390x_sha3_absorb, - s390x_kmac_final + s390x_kmac_final, + s390x_kmac_squeeze, }; +# define SHAKE_SET_MD(uname, typ) \ + if (S390_SHA3_CAPABLE(uname)) { \ + ctx->pad = S390X_##uname; \ + ctx->meth = typ##_s390x_md; \ + } else { \ + ctx->meth = shake_generic_md; \ + } + # define SHA3_SET_MD(uname, typ) \ if (S390_SHA3_CAPABLE(uname)) { \ ctx->pad = S390X_##uname; \ @@ -255,7 +413,7 @@ static PROV_SHA3_METHOD kmac_s390x_md = static sha3_absorb_fn armsha3_sha3_absorb; size_t SHA3_absorb_cext(uint64_t A[5][5], const unsigned char *inp, size_t len, - size_t r); + size_t r); /*- * Hardware-assisted ARMv8.2 SHA3 extension version of the absorb() */ @@ -271,6 +429,19 @@ static PROV_SHA3_METHOD sha3_ARMSHA3_md = armsha3_sha3_absorb, generic_sha3_final }; +static PROV_SHA3_METHOD shake_ARMSHA3_md = +{ + armsha3_sha3_absorb, + generic_sha3_final, + generic_sha3_squeeze +}; +# define SHAKE_SET_MD(uname, typ) \ + if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \ + ctx->meth = shake_ARMSHA3_md; \ + } else { \ + ctx->meth = shake_generic_md; \ + } + # define SHA3_SET_MD(uname, typ) \ if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \ ctx->meth = sha3_ARMSHA3_md; \ @@ -286,6 +457,7 @@ static PROV_SHA3_METHOD sha3_ARMSHA3_md = #else # define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md; # define KMAC_SET_MD(bitlen) ctx->meth = sha3_generic_md; +# define SHAKE_SET_MD(uname, typ) ctx->meth = shake_generic_md; #endif /* S390_SHA3 */ #define SHA3_newctx(typ, uname, name, bitlen, pad) \ @@ -302,6 +474,20 @@ static void *name##_newctx(void *provctx) \ return ctx; \ } +#define SHAKE_newctx(typ, uname, name, bitlen, pad) \ +static OSSL_FUNC_digest_newctx_fn name##_newctx; \ +static void *name##_newctx(void *provctx) \ +{ \ + KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx))\ + : NULL; \ + \ + if (ctx == NULL) \ + return NULL; \ + ossl_sha3_init(ctx, pad, bitlen); \ + SHAKE_SET_MD(uname, typ) \ + return ctx; \ +} + #define KMAC_newctx(uname, bitlen, pad) \ static OSSL_FUNC_digest_newctx_fn uname##_newctx; \ static void *uname##_newctx(void *provctx) \ @@ -333,6 +519,7 @@ const OSSL_DISPATCH ossl_##name##_functions[] = { \ #define PROV_FUNC_SHAKE_DIGEST(name, bitlen, blksize, dgstsize, flags) \ PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \ + { OSSL_FUNC_DIGEST_SQUEEZE, (void (*)(void))shake_squeeze }, \ { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init_params }, \ { OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))shake_set_ctx_params }, \ { OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, \ @@ -398,7 +585,7 @@ static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[]) SHA3_FLAGS) #define IMPLEMENT_SHAKE_functions(bitlen) \ - SHA3_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, '\x1f') \ + SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, '\x1f') \ PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen, \ SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \ SHAKE_FLAGS) diff --git a/libs/openssl-3/providers/implementations/include/prov/blake2.h b/libs/openssl-3/providers/implementations/include/prov/blake2.h index 445fd89aa..42229e2d7 100644 --- a/libs/openssl-3/providers/implementations/include/prov/blake2.h +++ b/libs/openssl-3/providers/implementations/include/prov/blake2.h @@ -88,6 +88,11 @@ struct blake2b_md_data_st { BLAKE2B_PARAM params; }; +struct blake2s_md_data_st { + BLAKE2S_CTX ctx; + BLAKE2S_PARAM params; +}; + int ossl_blake2b_init(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P); int ossl_blake2b_init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P, const void *key); @@ -125,4 +130,9 @@ void ossl_blake2s_param_set_personal(BLAKE2S_PARAM *P, const uint8_t *personal, void ossl_blake2s_param_set_salt(BLAKE2S_PARAM *P, const uint8_t *salt, size_t length); +OSSL_FUNC_digest_get_ctx_params_fn ossl_blake2s_get_ctx_params; +OSSL_FUNC_digest_set_ctx_params_fn ossl_blake2s_set_ctx_params; +OSSL_FUNC_digest_gettable_ctx_params_fn ossl_blake2s_gettable_ctx_params; +OSSL_FUNC_digest_settable_ctx_params_fn ossl_blake2s_settable_ctx_params; + #endif /* OSSL_PROV_BLAKE2_H */ diff --git a/libs/openssl-3/providers/implementations/include/prov/ciphercommon_gcm.h b/libs/openssl-3/providers/implementations/include/prov/ciphercommon_gcm.h index cd07c239b..ee0b23b92 100644 --- a/libs/openssl-3/providers/implementations/include/prov/ciphercommon_gcm.h +++ b/libs/openssl-3/providers/implementations/include/prov/ciphercommon_gcm.h @@ -1,6 +1,6 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-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 diff --git a/libs/openssl-3/providers/implementations/kdfs/krb5kdf.c b/libs/openssl-3/providers/implementations/kdfs/krb5kdf.c index b6cf0e3a2..bc951f741 100644 --- a/libs/openssl-3/providers/implementations/kdfs/krb5kdf.c +++ b/libs/openssl-3/providers/implementations/kdfs/krb5kdf.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. * * 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 @@ -416,6 +416,12 @@ static int KRB5KDF(const EVP_CIPHER *cipher, ENGINE *engine, /* Initialize input block */ blocksize = EVP_CIPHER_CTX_get_block_size(ctx); + if (blocksize == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER); + ret = 0; + goto out; + } + if (constant_len > blocksize) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONSTANT_LENGTH); ret = 0; diff --git a/libs/openssl-3/providers/implementations/kdfs/tls1_prf.c b/libs/openssl-3/providers/implementations/kdfs/tls1_prf.c index ff305579c..279248692 100644 --- a/libs/openssl-3/providers/implementations/kdfs/tls1_prf.c +++ b/libs/openssl-3/providers/implementations/kdfs/tls1_prf.c @@ -69,6 +69,9 @@ #include "prov/provider_util.h" #include "prov/securitycheck.h" #include "internal/e_os.h" +#include "internal/safe_math.h" + +OSSL_SAFE_MATH_UNSIGNED(size_t, size_t) static OSSL_FUNC_kdf_newctx_fn kdf_tls1_prf_new; static OSSL_FUNC_kdf_dupctx_fn kdf_tls1_prf_dup; @@ -85,7 +88,6 @@ static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx, const unsigned char *seed, size_t seed_len, unsigned char *out, size_t olen); -#define TLS1_PRF_MAXBUF 1024 #define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" #define TLS_MD_MASTER_SECRET_CONST_SIZE 13 @@ -101,8 +103,8 @@ typedef struct { /* Secret value to use for PRF */ unsigned char *sec; size_t seclen; - /* Buffer of concatenated seed data */ - unsigned char seed[TLS1_PRF_MAXBUF]; + /* Concatenated seed data */ + unsigned char *seed; size_t seedlen; } TLS1_PRF; @@ -136,7 +138,7 @@ static void kdf_tls1_prf_reset(void *vctx) EVP_MAC_CTX_free(ctx->P_hash); EVP_MAC_CTX_free(ctx->P_sha1); OPENSSL_clear_free(ctx->sec, ctx->seclen); - OPENSSL_cleanse(ctx->seed, ctx->seedlen); + OPENSSL_clear_free(ctx->seed, ctx->seedlen); memset(ctx, 0, sizeof(*ctx)); ctx->provctx = provctx; } @@ -156,8 +158,9 @@ static void *kdf_tls1_prf_dup(void *vctx) goto err; if (!ossl_prov_memdup(src->sec, src->seclen, &dest->sec, &dest->seclen)) goto err; - memcpy(dest->seed, src->seed, src->seedlen); - dest->seedlen = src->seedlen; + if (!ossl_prov_memdup(src->seed, src->seedlen, &dest->seed, + &dest->seedlen)) + goto err; } return dest; @@ -250,16 +253,29 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED)) != NULL) { for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, OSSL_KDF_PARAM_SEED)) { - const void *q = ctx->seed + ctx->seedlen; - size_t sz = 0; - - if (p->data_size != 0 - && p->data != NULL - && !OSSL_PARAM_get_octet_string(p, (void **)&q, - TLS1_PRF_MAXBUF - ctx->seedlen, - &sz)) - return 0; - ctx->seedlen += sz; + if (p->data_size != 0 && p->data != NULL) { + const void *val = NULL; + size_t sz = 0; + unsigned char *seed; + size_t seedlen; + int err = 0; + + if (!OSSL_PARAM_get_octet_string_ptr(p, &val, &sz)) + return 0; + + seedlen = safe_add_size_t(ctx->seedlen, sz, &err); + if (err) + return 0; + + seed = OPENSSL_clear_realloc(ctx->seed, ctx->seedlen, seedlen); + if (!seed) + return 0; + + ctx->seed = seed; + if (ossl_assert(sz != 0)) + memcpy(ctx->seed + ctx->seedlen, val, sz); + ctx->seedlen = seedlen; + } } } return 1; diff --git a/libs/openssl-3/providers/implementations/keymgmt/dh_kmgmt.c b/libs/openssl-3/providers/implementations/keymgmt/dh_kmgmt.c index 795a3f2fa..82c3093b1 100644 --- a/libs/openssl-3/providers/implementations/keymgmt/dh_kmgmt.c +++ b/libs/openssl-3/providers/implementations/keymgmt/dh_kmgmt.c @@ -12,6 +12,7 @@ * internal use. */ #include "internal/deprecated.h" +#include "internal/common.h" #include /* strcmp */ #include @@ -524,6 +525,7 @@ static int dh_gen_common_set_params(void *genctx, const OSSL_PARAM params[]) { struct dh_gen_ctx *gctx = genctx; const OSSL_PARAM *p; + int gen_type = -1; if (gctx == NULL) return 0; @@ -533,11 +535,13 @@ static int dh_gen_common_set_params(void *genctx, const OSSL_PARAM params[]) p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_TYPE); if (p != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING - || ((gctx->gen_type = + || ((gen_type = dh_gen_type_name2id_w_default(p->data, gctx->dh_type)) == -1)) { ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } + if (gen_type != -1) + gctx->gen_type = gen_type; } p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); if (p != NULL) { @@ -706,6 +710,19 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) if (gctx->group_nid != NID_undef) gctx->gen_type = DH_PARAMGEN_TYPE_GROUP; + /* + * Do a bounds check on context gen_type. Must be in range: + * DH_PARAMGEN_TYPE_GENERATOR <= gen_type <= DH_PARAMGEN_TYPE_GROUP + * Noted here as this needs to be adjusted if a new group type is + * added. + */ + if (!ossl_assert((gctx->gen_type >= DH_PARAMGEN_TYPE_GENERATOR) + && (gctx->gen_type <= DH_PARAMGEN_TYPE_GROUP))) { + ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR, + "gen_type set to unsupported value %d", gctx->gen_type); + return NULL; + } + /* For parameter generation - If there is a group name just create it */ if (gctx->gen_type == DH_PARAMGEN_TYPE_GROUP && gctx->ffc_params == NULL) { diff --git a/libs/openssl-3/providers/implementations/keymgmt/dsa_kmgmt.c b/libs/openssl-3/providers/implementations/keymgmt/dsa_kmgmt.c index a89d20822..88a2feda5 100644 --- a/libs/openssl-3/providers/implementations/keymgmt/dsa_kmgmt.c +++ b/libs/openssl-3/providers/implementations/keymgmt/dsa_kmgmt.c @@ -462,6 +462,7 @@ static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) { struct dsa_gen_ctx *gctx = genctx; const OSSL_PARAM *p; + int gen_type = -1; if (gctx == NULL) return 0; @@ -472,10 +473,18 @@ static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_TYPE); if (p != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING - || ((gctx->gen_type = dsa_gen_type_name2id(p->data)) == -1)) { + || ((gen_type = dsa_gen_type_name2id(p->data)) == -1)) { ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } + + /* + * Only assign context gen_type if it was set by dsa_gen_type_name2id + * must be in range: + * DSA_PARAMGEN_TYPE_FIPS_186_4 <= gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT + */ + if (gen_type != -1) + gctx->gen_type = gen_type; } p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX); if (p != NULL @@ -568,6 +577,19 @@ static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) gctx->gen_type = (gctx->pbits >= 2048 ? DSA_PARAMGEN_TYPE_FIPS_186_4 : DSA_PARAMGEN_TYPE_FIPS_186_2); + /* + * Do a bounds check on context gen_type. Must be in range: + * DSA_PARAMGEN_TYPE_FIPS_186_4 <= gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT + * Noted here as this needs to be adjusted if a new type is + * added. + */ + if (!ossl_assert((gctx->gen_type >= DSA_PARAMGEN_TYPE_FIPS_186_4) + && (gctx->gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT))) { + ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR, + "gen_type set to unsupported value %d", gctx->gen_type); + return NULL; + } + gctx->cb = osslcb; gctx->cbarg = cbarg; gencb = BN_GENCB_new(); diff --git a/libs/openssl-3/providers/implementations/keymgmt/ecx_kmgmt.c b/libs/openssl-3/providers/implementations/keymgmt/ecx_kmgmt.c index 8a9fe1b21..ae11fd4bc 100644 --- a/libs/openssl-3/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/libs/openssl-3/providers/implementations/keymgmt/ecx_kmgmt.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 @@ -16,6 +16,7 @@ #include #include #include +#include #include "internal/param_build_set.h" #include #include "crypto/ecx.h" @@ -588,6 +589,74 @@ static const OSSL_PARAM *ecx_gen_settable_params(ossl_unused void *genctx, return settable; } +#ifdef FIPS_MODULE +/* + * Refer: FIPS 140-3 IG 10.3.A Additional Comment 1 + * Perform a pairwise test for EDDSA by signing and verifying signature. + * + * The parameter `self_test` is used to indicate whether to create OSSL_SELF_TEST + * instance. + */ +static int ecd_fips140_pairwise_test(const ECX_KEY *ecx, int type, int self_test) +{ + int ret = 0; + OSSL_SELF_TEST *st = NULL; + OSSL_CALLBACK *cb = NULL; + void *cbarg = NULL; + + unsigned char msg[16] = {0}; + size_t msg_len = sizeof(msg); + unsigned char sig[ED448_SIGSIZE] = {0}; + + int is_ed25519 = (type == ECX_KEY_TYPE_ED25519) ? 1 : 0; + int operation_result = 0; + + /* + * The functions `OSSL_SELF_TEST_*` will return directly if parameter `st` + * is NULL. + */ + if (self_test) { + OSSL_SELF_TEST_get_callback(ecx->libctx, &cb, &cbarg); + + st = OSSL_SELF_TEST_new(cb, cbarg); + if (st == NULL) + return 0; + } + + OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, + OSSL_SELF_TEST_DESC_PCT_EDDSA); + + if (is_ed25519) + operation_result = ossl_ed25519_sign(sig, msg, msg_len, ecx->pubkey, + ecx->privkey, 0, 0, 0, NULL, 0, + ecx->libctx, ecx->propq); + else + operation_result = ossl_ed448_sign(ecx->libctx, sig, msg, msg_len, + ecx->pubkey, ecx->privkey, NULL, 0, + 0, ecx->propq); + if (operation_result != 1) + goto err; + + OSSL_SELF_TEST_oncorrupt_byte(st, sig); + + if (is_ed25519) + operation_result = ossl_ed25519_verify(msg, msg_len, sig, ecx->pubkey, + 0, 0, 0, NULL, 0, ecx->libctx, + ecx->propq); + else + operation_result = ossl_ed448_verify(ecx->libctx, msg, msg_len, sig, + ecx->pubkey, NULL, 0, 0, ecx->propq); + if (operation_result != 1) + goto err; + + ret = 1; +err: + OSSL_SELF_TEST_onend(st, ret); + OSSL_SELF_TEST_free(st); + return ret; +} +#endif + static void *ecx_gen(struct ecx_gen_ctx *gctx) { ECX_KEY *key; @@ -684,6 +753,7 @@ static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { + ECX_KEY *key = NULL; struct ecx_gen_ctx *gctx = genctx; if (!ossl_prov_is_running()) @@ -693,14 +763,31 @@ static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519) && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519) && OPENSSL_s390xcap_P.kdsa[0] - & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)) - return s390x_ecd_keygen25519(gctx); + & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)) { + key = s390x_ecd_keygen25519(gctx); + } else #endif - return ecx_gen(gctx); + { + key = ecx_gen(gctx); + } + +#ifdef FIPS_MODULE + /* Exit if keygen failed OR we are doing parameter generation (blank key) */ + if (!key || ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)) + return key; + if (ecd_fips140_pairwise_test(key, ECX_KEY_TYPE_ED25519, 1) != 1) { + ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); + ossl_ecx_key_free(key); + return NULL; + } +#endif + + return key; } static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { + ECX_KEY *key = NULL; struct ecx_gen_ctx *gctx = genctx; if (!ossl_prov_is_running()) @@ -709,10 +796,26 @@ static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) #ifdef S390X_EC_ASM if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448) && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448) - && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)) - return s390x_ecd_keygen448(gctx); + && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)) { + key = s390x_ecd_keygen448(gctx); + } else #endif - return ecx_gen(gctx); + { + key = ecx_gen(gctx); + } + +#ifdef FIPS_MODULE + /* Exit if keygen failed OR we are doing parameter generation (blank key) */ + if (!key || ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)) + return key; + if (ecd_fips140_pairwise_test(key, ECX_KEY_TYPE_ED448, 1) != 1) { + ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); + ossl_ecx_key_free(key); + return NULL; + } +#endif + + return key; } static void ecx_gen_cleanup(void *genctx) @@ -756,6 +859,23 @@ static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type) case ECX_KEY_TYPE_X448: ossl_x448_public_from_private(pub, ecx->privkey); break; + default: + return 0; + } + return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0; +} + +#ifdef FIPS_MODULE +static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type) +{ + return ecd_fips140_pairwise_test(ecx, type, 0); +} +#else +static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type) +{ + uint8_t pub[64]; + + switch (type) { case ECX_KEY_TYPE_ED25519: if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey, ecx->propq)) @@ -771,6 +891,7 @@ static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type) } return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0; } +#endif static int ecx_validate(const void *keydata, int selection, int type, size_t keylen) { @@ -794,7 +915,12 @@ static int ecx_validate(const void *keydata, int selection, int type, size_t key if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) ok = ok && ecx->privkey != NULL; - if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR) + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR) + return ok; + + if (type == ECX_KEY_TYPE_ED25519 || type == ECX_KEY_TYPE_ED448) + ok = ok && ecd_key_pairwise_check(ecx, type); + else ok = ok && ecx_key_pairwise_check(ecx, type); return ok; diff --git a/libs/openssl-3/providers/implementations/macs/hmac_prov.c b/libs/openssl-3/providers/implementations/macs/hmac_prov.c index a1f3c2db8..c72c1e6c0 100644 --- a/libs/openssl-3/providers/implementations/macs/hmac_prov.c +++ b/libs/openssl-3/providers/implementations/macs/hmac_prov.c @@ -274,23 +274,6 @@ static const OSSL_PARAM *hmac_settable_ctx_params(ossl_unused void *ctx, return known_settable_ctx_params; } -static int set_flag(const OSSL_PARAM params[], const char *key, int mask, - int *flags) -{ - const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, key); - int flag = 0; - - if (p != NULL) { - if (!OSSL_PARAM_get_int(p, &flag)) - return 0; - if (flag == 0) - *flags &= ~mask; - else - *flags |= mask; - } - return 1; -} - /* * ALL parameters should be set before init(). */ @@ -299,7 +282,6 @@ static int hmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[]) struct hmac_data_st *macctx = vmacctx; OSSL_LIB_CTX *ctx = PROV_LIBCTX_OF(macctx->provctx); const OSSL_PARAM *p; - int flags = 0; if (params == NULL) return 1; @@ -307,15 +289,6 @@ static int hmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[]) if (!ossl_prov_digest_load_from_params(&macctx->digest, params, ctx)) return 0; - if (!set_flag(params, OSSL_MAC_PARAM_DIGEST_NOINIT, EVP_MD_CTX_FLAG_NO_INIT, - &flags)) - return 0; - if (!set_flag(params, OSSL_MAC_PARAM_DIGEST_ONESHOT, EVP_MD_CTX_FLAG_ONESHOT, - &flags)) - return 0; - if (flags) - HMAC_CTX_set_flags(macctx->ctx, flags); - if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) return 0; diff --git a/libs/openssl-3/ssl/bio_ssl.c b/libs/openssl-3/ssl/bio_ssl.c index 68dd48a5e..aabd047fe 100644 --- a/libs/openssl-3/ssl/bio_ssl.c +++ b/libs/openssl-3/ssl/bio_ssl.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 @@ -174,7 +174,7 @@ static int ssl_write(BIO *b, const char *buf, size_t size, size_t *written) BIO_clear_retry_flags(b); - ret = ssl_write_internal(ssl, buf, size, written); + ret = ssl_write_internal(ssl, buf, size, 0, written); switch (SSL_get_error(ssl, ret)) { case SSL_ERROR_NONE: diff --git a/libs/openssl-3/ssl/d1_srtp.c b/libs/openssl-3/ssl/d1_srtp.c index 5ca135d97..155021ff5 100644 --- a/libs/openssl-3/ssl/d1_srtp.c +++ b/libs/openssl-3/ssl/d1_srtp.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,7 +20,7 @@ #ifndef OPENSSL_NO_SRTP -static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { +static const SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { { "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80, @@ -73,9 +73,9 @@ static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { }; static int find_profile_by_name(char *profile_name, - SRTP_PROTECTION_PROFILE **pptr, size_t len) + const SRTP_PROTECTION_PROFILE **pptr, size_t len) { - SRTP_PROTECTION_PROFILE *p; + const SRTP_PROTECTION_PROFILE *p; p = srtp_known_profiles; while (p->name) { @@ -98,7 +98,7 @@ static int ssl_ctx_make_profiles(const char *profiles_string, char *col; char *ptr = (char *)profiles_string; - SRTP_PROTECTION_PROFILE *p; + const SRTP_PROTECTION_PROFILE *p; if ((profiles = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); @@ -110,12 +110,14 @@ static int ssl_ctx_make_profiles(const char *profiles_string, if (!find_profile_by_name(ptr, &p, col ? (size_t)(col - ptr) : strlen(ptr))) { - if (sk_SRTP_PROTECTION_PROFILE_find(profiles, p) >= 0) { + if (sk_SRTP_PROTECTION_PROFILE_find(profiles, + (SRTP_PROTECTION_PROFILE *)p) >= 0) { ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); goto err; } - if (!sk_SRTP_PROTECTION_PROFILE_push(profiles, p)) { + if (!sk_SRTP_PROTECTION_PROFILE_push(profiles, + (SRTP_PROTECTION_PROFILE *)p)) { ERR_raise(ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); goto err; } diff --git a/libs/openssl-3/ssl/quic/json_enc.c b/libs/openssl-3/ssl/quic/json_enc.c new file mode 100644 index 000000000..3e9f715df --- /dev/null +++ b/libs/openssl-3/ssl/quic/json_enc.c @@ -0,0 +1,766 @@ +/* + * 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 + */ + +#include "internal/json_enc.h" +#include "internal/nelem.h" +#include "internal/numbers.h" +#include +#include + +/* + * wbuf + * ==== + */ +static int wbuf_flush(struct json_write_buf *wbuf, int full); + +static int wbuf_init(struct json_write_buf *wbuf, BIO *bio, size_t alloc) +{ + wbuf->buf = OPENSSL_malloc(alloc); + if (wbuf->buf == NULL) + return 0; + + wbuf->cur = 0; + wbuf->alloc = alloc; + wbuf->bio = bio; + return 1; +} + +static void wbuf_cleanup(struct json_write_buf *wbuf) +{ + OPENSSL_free(wbuf->buf); + wbuf->buf = NULL; + wbuf->alloc = 0; +} + +static void wbuf_set0_bio(struct json_write_buf *wbuf, BIO *bio) +{ + wbuf->bio = bio; +} + +/* Empty write buffer. */ +static ossl_inline void wbuf_clean(struct json_write_buf *wbuf) +{ + wbuf->cur = 0; +} + +/* Available data remaining in buffer. */ +static ossl_inline size_t wbuf_avail(struct json_write_buf *wbuf) +{ + return wbuf->alloc - wbuf->cur; +} + +/* Add character to write buffer, returning 0 on flush failure. */ +static ossl_inline int wbuf_write_char(struct json_write_buf *wbuf, char c) +{ + if (wbuf_avail(wbuf) == 0) { + if (!wbuf_flush(wbuf, /*full=*/0)) + return 0; + } + + wbuf->buf[wbuf->cur++] = c; + return 1; +} + +/* + * Write zero-terminated string to write buffer, returning 0 on flush failure. + */ +static int wbuf_write_str(struct json_write_buf *wbuf, const char *s) +{ + char c; + + while ((c = *s++) != 0) + if (!wbuf_write_char(wbuf, c)) + return 0; + + return 1; +} + +/* Flush write buffer, returning 0 on I/O failure. */ +static int wbuf_flush(struct json_write_buf *wbuf, int full) +{ + size_t written = 0, total_written = 0; + + while (total_written < wbuf->cur) { + if (!BIO_write_ex(wbuf->bio, + wbuf->buf + total_written, + wbuf->cur - total_written, + &written)) { + memmove(wbuf->buf, + wbuf->buf + total_written, + wbuf->cur - total_written); + wbuf->cur = 0; + return 0; + } + + total_written += written; + } + + wbuf->cur = 0; + + if (full) + (void)BIO_flush(wbuf->bio); /* best effort */ + + return 1; +} + +/* + * OSSL_JSON_ENC: Stack Management + * =============================== + */ + +static int json_ensure_stack_size(OSSL_JSON_ENC *json, size_t num_bytes) +{ + unsigned char *stack; + + if (json->stack_bytes >= num_bytes) + return 1; + + if (num_bytes <= OSSL_NELEM(json->stack_small)) { + stack = json->stack_small; + } else { + if (json->stack == json->stack_small) + json->stack = NULL; + + stack = OPENSSL_realloc(json->stack, num_bytes); + if (stack == NULL) + return 0; + } + + json->stack = stack; + json->stack_bytes = num_bytes; + return 1; +} + +/* Push one bit onto the stack. Returns 0 on allocation failure. */ +static int json_push(OSSL_JSON_ENC *json, unsigned int v) +{ + if (v > 1) + return 0; + + if (json->stack_end_byte >= json->stack_bytes) { + size_t new_size + = (json->stack_bytes == 0) + ? OSSL_NELEM(json->stack_small) + : (json->stack_bytes * 2); + + if (!json_ensure_stack_size(json, new_size)) + return 0; + + json->stack_bytes = new_size; + } + + if (v > 0) + json->stack[json->stack_end_byte] |= (v << json->stack_end_bit); + else + json->stack[json->stack_end_byte] &= ~(1U << json->stack_end_bit); + + json->stack_end_bit = (json->stack_end_bit + 1) % CHAR_BIT; + if (json->stack_end_bit == 0) + ++json->stack_end_byte; + + return 1; +} + +/* + * Pop a bit from the stack. Returns 0 if stack is empty. Use json_peek() to get + * the value before calling this. + */ +static int json_pop(OSSL_JSON_ENC *json) +{ + if (json->stack_end_byte == 0 && json->stack_end_bit == 0) + return 0; + + if (json->stack_end_bit == 0) { + --json->stack_end_byte; + json->stack_end_bit = CHAR_BIT - 1; + } else { + --json->stack_end_bit; + } + + return 1; +} + +/* + * Returns the bit on the top of the stack, or -1 if the stack is empty. + */ +static int json_peek(OSSL_JSON_ENC *json) +{ + size_t obyte, obit; + + obyte = json->stack_end_byte; + obit = json->stack_end_bit; + if (obit == 0) { + if (obyte == 0) + return -1; + + --obyte; + obit = CHAR_BIT - 1; + } else { + --obit; + } + + return (json->stack[obyte] & (1U << obit)) != 0; +} + +/* + * OSSL_JSON_ENC: Initialisation + * ============================= + */ + +enum { + STATE_PRE_KEY, + STATE_PRE_ITEM, + STATE_PRE_COMMA +}; + +static ossl_inline int in_ijson(const OSSL_JSON_ENC *json) +{ + return (json->flags & OSSL_JSON_FLAG_IJSON) != 0; +} + +static ossl_inline int in_seq(const OSSL_JSON_ENC *json) +{ + return (json->flags & OSSL_JSON_FLAG_SEQ) != 0; +} + +static ossl_inline int in_pretty(const OSSL_JSON_ENC *json) +{ + return (json->flags & OSSL_JSON_FLAG_PRETTY) != 0; +} + +int ossl_json_init(OSSL_JSON_ENC *json, BIO *bio, uint32_t flags) +{ + memset(json, 0, sizeof(*json)); + json->flags = flags; + json->error = 0; + if (!wbuf_init(&json->wbuf, bio, 4096)) + return 0; + + json->state = STATE_PRE_COMMA; + return 1; +} + +void ossl_json_cleanup(OSSL_JSON_ENC *json) +{ + wbuf_cleanup(&json->wbuf); + + if (json->stack != json->stack_small) + OPENSSL_free(json->stack); + + json->stack = NULL; +} + +int ossl_json_flush_cleanup(OSSL_JSON_ENC *json) +{ + int ok = ossl_json_flush(json); + + ossl_json_cleanup(json); + return ok; +} + +int ossl_json_reset(OSSL_JSON_ENC *json) +{ + wbuf_clean(&json->wbuf); + json->stack_end_byte = 0; + json->stack_end_bit = 0; + json->error = 0; + return 1; +} + +int ossl_json_flush(OSSL_JSON_ENC *json) +{ + return wbuf_flush(&json->wbuf, /*full=*/1); +} + +int ossl_json_set0_sink(OSSL_JSON_ENC *json, BIO *bio) +{ + wbuf_set0_bio(&json->wbuf, bio); + return 1; +} + +int ossl_json_in_error(OSSL_JSON_ENC *json) +{ + return json->error; +} + +/* + * JSON Builder Calls + * ================== + */ + +static void json_write_qstring(OSSL_JSON_ENC *json, const char *str); +static void json_indent(OSSL_JSON_ENC *json); + +static void json_raise_error(OSSL_JSON_ENC *json) +{ + json->error = 1; +} + +static void json_undefer(OSSL_JSON_ENC *json) +{ + if (!json->defer_indent) + return; + + json_indent(json); +} + +static void json_write_char(OSSL_JSON_ENC *json, char ch) +{ + if (ossl_json_in_error(json)) + return; + + json_undefer(json); + if (!wbuf_write_char(&json->wbuf, ch)) + json_raise_error(json); +} + +static void json_write_str(OSSL_JSON_ENC *json, const char *s) +{ + if (ossl_json_in_error(json)) + return; + + json_undefer(json); + if (!wbuf_write_str(&json->wbuf, s)) + json_raise_error(json); +} + +static void json_indent(OSSL_JSON_ENC *json) +{ + size_t i, depth; + + json->defer_indent = 0; + + if (!in_pretty(json)) + return; + + json_write_char(json, '\n'); + + depth = json->stack_end_byte * 8 + json->stack_end_bit; + for (i = 0; i < depth * 4; ++i) + json_write_str(json, " "); +} + +static int json_pre_item(OSSL_JSON_ENC *json) +{ + int s; + + if (ossl_json_in_error(json)) + return 0; + + switch (json->state) { + case STATE_PRE_COMMA: + s = json_peek(json); + + if (s == 0) { + json_raise_error(json); + return 0; + } + + if (s == 1) { + json_write_char(json, ','); + if (ossl_json_in_error(json)) + return 0; + + json_indent(json); + } + + if (s < 0 && in_seq(json)) + json_write_char(json, '\x1E'); + + json->state = STATE_PRE_ITEM; + break; + + case STATE_PRE_ITEM: + break; + + case STATE_PRE_KEY: + default: + json_raise_error(json); + return 0; + } + + return 1; +} + +static void json_post_item(OSSL_JSON_ENC *json) +{ + int s = json_peek(json); + + json->state = STATE_PRE_COMMA; + + if (s < 0 && in_seq(json)) + json_write_char(json, '\n'); +} + +/* + * Begin a composite structure (object or array). + * + * type: 0=object, 1=array. + */ +static void composite_begin(OSSL_JSON_ENC *json, int type, char ch) +{ + if (!json_pre_item(json) + || !json_push(json, type)) + json_raise_error(json); + + json_write_char(json, ch); + json->defer_indent = 1; +} + +/* + * End a composite structure (object or array). + * + * type: 0=object, 1=array. Errors on mismatch. + */ +static void composite_end(OSSL_JSON_ENC *json, int type, char ch) +{ + int was_defer = json->defer_indent; + + if (ossl_json_in_error(json)) + return; + + json->defer_indent = 0; + + if (json_peek(json) != type) { + json_raise_error(json); + return; + } + + if (type == 0 && json->state == STATE_PRE_ITEM) { + json_raise_error(json); + return; + } + + if (!json_pop(json)) { + json_raise_error(json); + return; + } + + if (!was_defer) + json_indent(json); + + json_write_char(json, ch); + json_post_item(json); +} + +/* Begin a new JSON object. */ +void ossl_json_object_begin(OSSL_JSON_ENC *json) +{ + composite_begin(json, 0, '{'); + json->state = STATE_PRE_KEY; +} + +/* End a JSON object. Must be matched with a call to ossl_json_object_begin(). */ +void ossl_json_object_end(OSSL_JSON_ENC *json) +{ + composite_end(json, 0, '}'); +} + +/* Begin a new JSON array. */ +void ossl_json_array_begin(OSSL_JSON_ENC *json) +{ + composite_begin(json, 1, '['); + json->state = STATE_PRE_ITEM; +} + +/* End a JSON array. Must be matched with a call to ossl_json_array_begin(). */ +void ossl_json_array_end(OSSL_JSON_ENC *json) +{ + composite_end(json, 1, ']'); +} + +/* + * 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) +{ + if (ossl_json_in_error(json)) + return; + + if (json_peek(json) != 0) { + /* Not in object */ + json_raise_error(json); + return; + } + + if (json->state == STATE_PRE_COMMA) { + json_write_char(json, ','); + json->state = STATE_PRE_KEY; + } + + json_indent(json); + if (json->state != STATE_PRE_KEY) { + json_raise_error(json); + return; + } + + json_write_qstring(json, key); + if (ossl_json_in_error(json)) + return; + + json_write_char(json, ':'); + if (in_pretty(json)) + json_write_char(json, ' '); + + json->state = STATE_PRE_ITEM; +} + +/* Encode a JSON 'null' value. */ +void ossl_json_null(OSSL_JSON_ENC *json) +{ + if (!json_pre_item(json)) + return; + + json_write_str(json, "null"); + json_post_item(json); +} + +void ossl_json_bool(OSSL_JSON_ENC *json, int v) +{ + if (!json_pre_item(json)) + return; + + json_write_str(json, v > 0 ? "true" : "false"); + json_post_item(json); +} + +#define POW_53 (((int64_t)1) << 53) + +/* Encode a JSON integer from a uint64_t. */ +static void json_u64(OSSL_JSON_ENC *json, uint64_t v, int noquote) +{ + char buf[22], *p = buf + sizeof(buf) - 1; + int quote = !noquote && in_ijson(json) && v > (uint64_t)(POW_53 - 1); + + if (!json_pre_item(json)) + return; + + if (quote) + json_write_char(json, '"'); + + if (v == 0) + p = "0"; + else + for (*p = '\0'; v > 0; v /= 10) + *--p = '0' + v % 10; + + json_write_str(json, p); + + if (quote) + json_write_char(json, '"'); + + json_post_item(json); +} + +void ossl_json_u64(OSSL_JSON_ENC *json, uint64_t v) +{ + json_u64(json, v, 0); +} + +/* Encode a JSON integer from an int64_t. */ +void ossl_json_i64(OSSL_JSON_ENC *json, int64_t value) +{ + uint64_t uv; + int quote; + + if (value >= 0) { + ossl_json_u64(json, (uint64_t)value); + return; + } + + if (!json_pre_item(json)) + return; + + quote = in_ijson(json) + && (value > POW_53 - 1 || value < -POW_53 + 1); + + if (quote) + json_write_char(json, '"'); + + json_write_char(json, '-'); + + uv = (value == INT64_MIN) + ? ((uint64_t)-(INT64_MIN + 1)) + 1 + : (uint64_t)-value; + json_u64(json, uv, /*noquote=*/1); + + if (quote && !ossl_json_in_error(json)) + json_write_char(json, '"'); +} + +/* Encode a JSON number from a 64-bit floating point value. */ +void ossl_json_f64(OSSL_JSON_ENC *json, double value) +{ + char buf[32]; + + if (!json_pre_item(json)) + return; + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + { + int checks = isnan(value); +# if !defined(OPENSSL_SYS_VMS) + checks |= isinf(value); +# endif + + if (checks) { + json_raise_error(json); + return; + } + } +#endif + + BIO_snprintf(buf, sizeof(buf), "%1.17g", value); + json_write_str(json, buf); + json_post_item(json); +} + +/* + * Encode a JSON UTF-8 string from a zero-terminated string. The string passed + * can be freed immediately following the call to this function. + */ +static ossl_inline int hex_digit(int v) +{ + return v >= 10 ? 'a' + (v - 10) : '0' + v; +} + +static ossl_inline void +json_write_qstring_inner(OSSL_JSON_ENC *json, const char *str, size_t str_len, + int nul_term) +{ + char c, *o, obuf[7]; + unsigned char *u_str; + int i; + size_t j; + + if (ossl_json_in_error(json)) + return; + + json_write_char(json, '"'); + + for (j = nul_term ? strlen(str) : str_len; j > 0; str++, j--) { + c = *str; + u_str = (unsigned char*)str; + switch (c) { + case '\n': o = "\\n"; break; + case '\r': o = "\\r"; break; + case '\t': o = "\\t"; break; + case '\b': o = "\\b"; break; + case '\f': o = "\\f"; break; + case '"': o = "\\\""; break; + case '\\': o = "\\\\"; break; + default: + /* valid UTF-8 sequences according to RFC-3629 */ + if (u_str[0] >= 0xc2 && u_str[0] <= 0xdf && j >= 2 + && u_str[1] >= 0x80 && u_str[1] <= 0xbf) { + memcpy(obuf, str, 2); + obuf[2] = '\0'; + str++, j--; + o = obuf; + break; + } + if (u_str[0] >= 0xe0 && u_str[0] <= 0xef && j >= 3 + && u_str[1] >= 0x80 && u_str[1] <= 0xbf + && u_str[2] >= 0x80 && u_str[2] <= 0xbf + && !(u_str[0] == 0xe0 && u_str[1] <= 0x9f) + && !(u_str[0] == 0xed && u_str[1] >= 0xa0)) { + memcpy(obuf, str, 3); + obuf[3] = '\0'; + str += 2; + j -= 2; + o = obuf; + break; + } + if (u_str[0] >= 0xf0 && u_str[0] <= 0xf4 && j >= 4 + && u_str[1] >= 0x80 && u_str[1] <= 0xbf + && u_str[2] >= 0x80 && u_str[2] <= 0xbf + && u_str[3] >= 0x80 && u_str[3] <= 0xbf + && !(u_str[0] == 0xf0 && u_str[1] <= 0x8f) + && !(u_str[0] == 0xf4 && u_str[1] >= 0x90)) { + memcpy(obuf, str, 4); + obuf[4] = '\0'; + str += 3; + j -= 3; + o = obuf; + break; + } + if (u_str[0] < 0x20 || u_str[0] >= 0x7f) { + obuf[0] = '\\'; + obuf[1] = 'u'; + for (i = 0; i < 4; ++i) + obuf[2 + i] = hex_digit((u_str[0] >> ((3 - i) * 4)) & 0x0F); + obuf[6] = '\0'; + o = obuf; + } else { + json_write_char(json, c); + continue; + } + break; + } + + json_write_str(json, o); + } + + json_write_char(json, '"'); +} + +static void +json_write_qstring(OSSL_JSON_ENC *json, const char *str) +{ + json_write_qstring_inner(json, str, 0, 1); +} + +static void +json_write_qstring_len(OSSL_JSON_ENC *json, const char *str, size_t str_len) +{ + json_write_qstring_inner(json, str, str_len, 0); +} + +void ossl_json_str(OSSL_JSON_ENC *json, const char *str) +{ + if (!json_pre_item(json)) + return; + + json_write_qstring(json, str); + json_post_item(json); +} + +void ossl_json_str_len(OSSL_JSON_ENC *json, const char *str, size_t str_len) +{ + if (!json_pre_item(json)) + return; + + json_write_qstring_len(json, str, str_len); + json_post_item(json); +} + +/* + * 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) +{ + const unsigned char *b = data, *end = b + data_len; + unsigned char c; + + if (!json_pre_item(json)) + return; + + json_write_char(json, '"'); + + for (; b < end; ++b) { + c = *b; + json_write_char(json, hex_digit(c >> 4)); + json_write_char(json, hex_digit(c & 0x0F)); + } + + json_write_char(json, '"'); + json_post_item(json); +} diff --git a/libs/openssl-3/ssl/quic/qlog.c b/libs/openssl-3/ssl/quic/qlog.c new file mode 100644 index 000000000..3aadda046 --- /dev/null +++ b/libs/openssl-3/ssl/quic/qlog.c @@ -0,0 +1,728 @@ +/* + * 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 + */ + +#include "internal/qlog.h" +#include "internal/json_enc.h" +#include "internal/common.h" +#include "internal/cryptlib.h" +#include "crypto/ctype.h" + +#define BITS_PER_WORD (sizeof(size_t) * 8) +#define NUM_ENABLED_W ((QLOG_EVENT_TYPE_NUM + BITS_PER_WORD - 1) / BITS_PER_WORD) + +static ossl_unused ossl_inline int bit_get(const size_t *p, uint32_t bit_no) +{ + return p[bit_no / BITS_PER_WORD] & (((size_t)1) << (bit_no % BITS_PER_WORD)); +} + +static ossl_unused ossl_inline void bit_set(size_t *p, uint32_t bit_no, int enable) +{ + size_t mask = (((size_t)1) << (bit_no % BITS_PER_WORD)); + + if (enable) + p[bit_no / BITS_PER_WORD] |= mask; + else + p[bit_no / BITS_PER_WORD] &= ~mask; +} + +struct qlog_st { + QLOG_TRACE_INFO info; + + BIO *bio; + size_t enabled[NUM_ENABLED_W]; + uint32_t event_type; + const char *event_cat, *event_name, *event_combined_name; + OSSL_TIME event_time, prev_event_time; + OSSL_JSON_ENC json; + int header_done, first_event_done; +}; + +static OSSL_TIME default_now(void *arg) +{ + return ossl_time_now(); +} + +/* + * Construction + * ============ + */ +QLOG *ossl_qlog_new(const QLOG_TRACE_INFO *info) +{ + QLOG *qlog = OPENSSL_zalloc(sizeof(QLOG)); + + if (qlog == NULL) + return NULL; + + qlog->info.odcid = info->odcid; + qlog->info.is_server = info->is_server; + qlog->info.now_cb = info->now_cb; + qlog->info.now_cb_arg = info->now_cb_arg; + qlog->info.override_process_id = info->override_process_id; + + if (info->title != NULL + && (qlog->info.title = OPENSSL_strdup(info->title)) == NULL) + goto err; + + if (info->description != NULL + && (qlog->info.description = OPENSSL_strdup(info->description)) == NULL) + goto err; + + if (info->group_id != NULL + && (qlog->info.group_id = OPENSSL_strdup(info->group_id)) == NULL) + goto err; + + if (info->override_impl_name != NULL + && (qlog->info.override_impl_name + = OPENSSL_strdup(info->override_impl_name)) == NULL) + goto err; + + if (!ossl_json_init(&qlog->json, NULL, + OSSL_JSON_FLAG_IJSON | OSSL_JSON_FLAG_SEQ)) + goto err; + + if (qlog->info.now_cb == NULL) + qlog->info.now_cb = default_now; + + return qlog; + +err: + if (qlog != NULL) { + OPENSSL_free((char *)qlog->info.title); + OPENSSL_free((char *)qlog->info.description); + OPENSSL_free((char *)qlog->info.group_id); + OPENSSL_free((char *)qlog->info.override_impl_name); + OPENSSL_free(qlog); + } + return NULL; +} + +QLOG *ossl_qlog_new_from_env(const QLOG_TRACE_INFO *info) +{ + QLOG *qlog = NULL; + const char *qlogdir = ossl_safe_getenv("QLOGDIR"); + const char *qfilter = ossl_safe_getenv("OSSL_QFILTER"); + char qlogdir_sep, *filename = NULL; + size_t i, l, strl; + + if (info == NULL || qlogdir == NULL) + return NULL; + + l = strlen(qlogdir); + if (l == 0) + return NULL; + + qlogdir_sep = ossl_determine_dirsep(qlogdir); + + /* dir; [sep]; ODCID; _; strlen("client" / "server"); strlen(".sqlog"); NUL */ + strl = l + 1 + info->odcid.id_len * 2 + 1 + 6 + 6 + 1; + filename = OPENSSL_malloc(strl); + if (filename == NULL) + return NULL; + + memcpy(filename, qlogdir, l); + if (qlogdir_sep != '\0') + filename[l++] = qlogdir_sep; + + for (i = 0; i < info->odcid.id_len; ++i) + l += BIO_snprintf(filename + l, strl - l, "%02x", info->odcid.id[i]); + + l += BIO_snprintf(filename + l, strl - l, "_%s.sqlog", + info->is_server ? "server" : "client"); + + qlog = ossl_qlog_new(info); + if (qlog == NULL) + goto err; + + if (!ossl_qlog_set_sink_filename(qlog, filename)) + goto err; + + if (qfilter == NULL || qfilter[0] == '\0') + qfilter = "*"; + + if (!ossl_qlog_set_filter(qlog, qfilter)) + goto err; + + OPENSSL_free(filename); + return qlog; + +err: + OPENSSL_free(filename); + ossl_qlog_free(qlog); + return NULL; +} + +void ossl_qlog_free(QLOG *qlog) +{ + if (qlog == NULL) + return; + + ossl_json_flush_cleanup(&qlog->json); + BIO_free_all(qlog->bio); + OPENSSL_free((char *)qlog->info.title); + OPENSSL_free((char *)qlog->info.description); + OPENSSL_free((char *)qlog->info.group_id); + OPENSSL_free((char *)qlog->info.override_impl_name); + OPENSSL_free(qlog); +} + +/* + * Configuration + * ============= + */ +int ossl_qlog_set_sink_bio(QLOG *qlog, BIO *bio) +{ + if (qlog == NULL) + return 0; + + ossl_qlog_flush(qlog); /* best effort */ + BIO_free_all(qlog->bio); + qlog->bio = bio; + ossl_json_set0_sink(&qlog->json, bio); + return 1; +} + +#ifndef OPENSSL_NO_STDIO + +int ossl_qlog_set_sink_file(QLOG *qlog, FILE *f, int close_flag) +{ + BIO *bio; + + if (qlog == NULL) + return 0; + + bio = BIO_new_fp(f, BIO_CLOSE); + if (bio == NULL) + return 0; + + if (!ossl_qlog_set_sink_bio(qlog, bio)) { + BIO_free_all(bio); + return 0; + } + + return 1; +} + +#endif + +int ossl_qlog_set_sink_filename(QLOG *qlog, const char *filename) +{ + BIO *bio; + + if (qlog == NULL) + return 0; + + /* + * We supply our own text encoding as JSON requires UTF-8, so disable any + * OS-specific processing here. + */ + bio = BIO_new_file(filename, "wb"); + if (bio == NULL) + return 0; + + if (!ossl_qlog_set_sink_bio(qlog, bio)) { + BIO_free_all(bio); + return 0; + } + + return 1; +} + +int ossl_qlog_flush(QLOG *qlog) +{ + if (qlog == NULL) + return 1; + + return ossl_json_flush(&qlog->json); +} + +int ossl_qlog_set_event_type_enabled(QLOG *qlog, uint32_t event_type, + int enabled) +{ + if (qlog == NULL || event_type >= QLOG_EVENT_TYPE_NUM) + return 0; + + bit_set(qlog->enabled, event_type, enabled); + return 1; +} + +int ossl_qlog_enabled(QLOG *qlog, uint32_t event_type) +{ + if (qlog == NULL) + return 0; + + return bit_get(qlog->enabled, event_type) != 0; +} + +/* + * Event Lifecycle + * =============== + */ +static void write_str_once(QLOG *qlog, const char *key, char **p) +{ + if (*p == NULL) + return; + + ossl_json_key(&qlog->json, key); + ossl_json_str(&qlog->json, *p); + + OPENSSL_free(*p); + *p = NULL; +} + +static void qlog_event_seq_header(QLOG *qlog) +{ + if (qlog->header_done) + return; + + ossl_json_object_begin(&qlog->json); + { + ossl_json_key(&qlog->json, "qlog_version"); + ossl_json_str(&qlog->json, "0.3"); + + ossl_json_key(&qlog->json, "qlog_format"); + ossl_json_str(&qlog->json, "JSON-SEQ"); + + write_str_once(qlog, "title", (char **)&qlog->info.title); + write_str_once(qlog, "description", (char **)&qlog->info.description); + + ossl_json_key(&qlog->json, "trace"); + ossl_json_object_begin(&qlog->json); + { + ossl_json_key(&qlog->json, "common_fields"); + ossl_json_object_begin(&qlog->json); + { + ossl_json_key(&qlog->json, "time_format"); + ossl_json_str(&qlog->json, "delta"); + + ossl_json_key(&qlog->json, "protocol_type"); + ossl_json_array_begin(&qlog->json); + { + ossl_json_str(&qlog->json, "QUIC"); + } /* protocol_type */ + ossl_json_array_end(&qlog->json); + + write_str_once(qlog, "group_id", (char **)&qlog->info.group_id); + + ossl_json_key(&qlog->json, "system_info"); + ossl_json_object_begin(&qlog->json); + { + if (qlog->info.override_process_id != 0) { + ossl_json_key(&qlog->json, "process_id"); + ossl_json_u64(&qlog->json, qlog->info.override_process_id); + } else { +#if defined(OPENSSL_SYS_UNIX) + ossl_json_key(&qlog->json, "process_id"); + ossl_json_u64(&qlog->json, (uint64_t)getpid()); +#elif defined(OPENSSL_SYS_WINDOWS) + ossl_json_key(&qlog->json, "process_id"); + ossl_json_u64(&qlog->json, (uint64_t)GetCurrentProcessId()); +#endif + } + } /* system_info */ + ossl_json_object_end(&qlog->json); + } /* common_fields */ + ossl_json_object_end(&qlog->json); + + ossl_json_key(&qlog->json, "vantage_point"); + ossl_json_object_begin(&qlog->json); + { + char buf[128]; + const char *p = buf; + + if (qlog->info.override_impl_name != NULL) { + p = qlog->info.override_impl_name; + } else { + BIO_snprintf(buf, sizeof(buf), "OpenSSL/%s (%s)", + OpenSSL_version(OPENSSL_FULL_VERSION_STRING), + OpenSSL_version(OPENSSL_PLATFORM) + 10); + } + + ossl_json_key(&qlog->json, "type"); + ossl_json_str(&qlog->json, + qlog->info.is_server ? "server" : "client"); + + ossl_json_key(&qlog->json, "name"); + ossl_json_str(&qlog->json, p); + } /* vantage_point */ + ossl_json_object_end(&qlog->json); + } /* trace */ + ossl_json_object_end(&qlog->json); + } + ossl_json_object_end(&qlog->json); + + qlog->header_done = 1; +} + +static void qlog_event_prologue(QLOG *qlog) +{ + qlog_event_seq_header(qlog); + + ossl_json_object_begin(&qlog->json); + + ossl_json_key(&qlog->json, "name"); + ossl_json_str(&qlog->json, qlog->event_combined_name); + + ossl_json_key(&qlog->json, "data"); + ossl_json_object_begin(&qlog->json); +} + +static void qlog_event_epilogue(QLOG *qlog) +{ + ossl_json_object_end(&qlog->json); + + ossl_json_key(&qlog->json, "time"); + if (!qlog->first_event_done) { + ossl_json_u64(&qlog->json, ossl_time2ms(qlog->event_time)); + qlog->prev_event_time = qlog->event_time; + qlog->first_event_done = 1; + } else { + OSSL_TIME delta = ossl_time_subtract(qlog->event_time, + qlog->prev_event_time); + + ossl_json_u64(&qlog->json, ossl_time2ms(delta)); + qlog->prev_event_time = qlog->event_time; + } + + ossl_json_object_end(&qlog->json); +} + +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) +{ + if (qlog == NULL) + return 0; + + if (!ossl_assert(qlog->event_type == QLOG_EVENT_TYPE_NONE) + || !ossl_qlog_enabled(qlog, event_type)) + return 0; + + qlog->event_type = event_type; + qlog->event_cat = event_cat; + qlog->event_name = event_name; + qlog->event_combined_name = event_combined_name; + qlog->event_time = qlog->info.now_cb(qlog->info.now_cb_arg); + + qlog_event_prologue(qlog); + return 1; +} + +void ossl_qlog_event_end(QLOG *qlog) +{ + if (!ossl_assert(qlog != NULL && qlog->event_type != QLOG_EVENT_TYPE_NONE)) + return; + + qlog_event_epilogue(qlog); + qlog->event_type = QLOG_EVENT_TYPE_NONE; +} + +/* + * Field Generators + * ================ + */ +void ossl_qlog_group_begin(QLOG *qlog, const char *name) +{ + if (name != NULL) + ossl_json_key(&qlog->json, name); + + ossl_json_object_begin(&qlog->json); +} + +void ossl_qlog_group_end(QLOG *qlog) +{ + ossl_json_object_end(&qlog->json); +} + +void ossl_qlog_array_begin(QLOG *qlog, const char *name) +{ + if (name != NULL) + ossl_json_key(&qlog->json, name); + + ossl_json_array_begin(&qlog->json); +} + +void ossl_qlog_array_end(QLOG *qlog) +{ + ossl_json_array_end(&qlog->json); +} + +void ossl_qlog_override_time(QLOG *qlog, OSSL_TIME event_time) +{ + qlog->event_time = event_time; +} + +void ossl_qlog_str(QLOG *qlog, const char *name, const char *value) +{ + if (name != NULL) + ossl_json_key(&qlog->json, name); + + ossl_json_str(&qlog->json, value); +} + +void ossl_qlog_str_len(QLOG *qlog, const char *name, + const char *value, size_t value_len) +{ + if (name != NULL) + ossl_json_key(&qlog->json, name); + + ossl_json_str_len(&qlog->json, value, value_len); +} + +void ossl_qlog_u64(QLOG *qlog, const char *name, uint64_t value) +{ + if (name != NULL) + ossl_json_key(&qlog->json, name); + + ossl_json_u64(&qlog->json, value); +} + +void ossl_qlog_i64(QLOG *qlog, const char *name, int64_t value) +{ + if (name != NULL) + ossl_json_key(&qlog->json, name); + + ossl_json_i64(&qlog->json, value); +} + +void ossl_qlog_bool(QLOG *qlog, const char *name, int value) +{ + if (name != NULL) + ossl_json_key(&qlog->json, name); + + ossl_json_bool(&qlog->json, value); +} + +void ossl_qlog_bin(QLOG *qlog, const char *name, + const void *value, size_t value_len) +{ + if (name != NULL) + ossl_json_key(&qlog->json, name); + + ossl_json_str_hex(&qlog->json, value, value_len); +} + +/* + * Filter Parsing + * ============== + */ +struct lexer { + const char *p, *term_end, *end; +}; + +static ossl_inline int is_term_sep_ws(char c) +{ + return c == ' ' || c == '\r' || c == '\n' || c == '\t'; +} + +static ossl_inline int is_name_char(char c) +{ + return ossl_isalpha(c) || ossl_isdigit(c) || c == '_' || c == '-'; +} + +static int lex_init(struct lexer *lex, const char *in, size_t in_len) +{ + if (in == NULL) + return 0; + + lex->p = in; + lex->term_end = in; + lex->end = in + in_len; + return 1; +} + +static int lex_do(struct lexer *lex) +{ + const char *p = lex->term_end, *end = lex->end, *term_end; + + for (; is_term_sep_ws(*p) && p < end; ++p); + + if (p == end) { + lex->p = end; + lex->term_end = end; + return 0; + } + + for (term_end = p; !is_term_sep_ws(*term_end) && term_end < end; ++term_end); + + lex->p = p; + lex->term_end = term_end; + return 1; +} + +static int lex_eot(struct lexer *lex) +{ + return lex->p == lex->term_end; +} + +static int lex_peek_char(struct lexer *lex) +{ + return lex_eot(lex) ? -1 : *lex->p; +} + +static int lex_skip_char(struct lexer *lex) +{ + if (lex_eot(lex)) + return 0; + + ++lex->p; + return 1; +} + +static int lex_match(struct lexer *lex, const char *s, size_t s_len) +{ + if ((size_t)(lex->term_end - lex->p) != s_len) + return 0; + + if (memcmp(lex->p, s, s_len)) + return 0; + + return 1; +} + +static void lex_get_rest(struct lexer *lex, const char **str, size_t *str_l) +{ + *str = lex->p; + *str_l = lex->term_end - lex->p; +} + +static int lex_extract_to(struct lexer *lex, char c, + const char **str, size_t *str_l) +{ + const char *p = lex->p, *term_end = lex->term_end, *s; + + for (s = p; s < term_end && *s != c; ++s); + if (s == term_end) + return 0; + + *str = p; + *str_l = s - p; + lex->p = ++s; + return 1; +} + +static int ossl_unused filter_match_event(const char *cat, size_t cat_l, + const char *event, size_t event_l, + const char *expect_cat, + const char *expect_event) +{ + size_t expect_cat_l = strlen(expect_cat); + size_t expect_event_l = strlen(expect_event); + + if ((cat != NULL && cat_l != expect_cat_l) + || (event != NULL && event_l != expect_event_l) + || (cat != NULL && memcmp(cat, expect_cat, expect_cat_l)) + || (event != NULL && memcmp(event, expect_event, expect_event_l))) + return 0; + + return 1; +} + +/* + * enabled: event enablement bitmask Array of size NUM_ENABLED_W. + * add: 1 to enable an event, 0 to disable. + * cat: Category name/length. Not necessarily zero terminated. + * NULL to match any. + * event: Event name/length. Not necessarily zero terminated. + * NULL to match any. + */ +static void filter_apply(size_t *enabled, int add, + const char *cat, size_t cat_l, + const char *event, size_t event_l) +{ + /* Find events which match the given filters. */ +# define QLOG_EVENT(e_cat, e_name) \ + if (filter_match_event(cat, cat_l, event, event_l, \ + #e_cat, #e_name)) \ + bit_set(enabled, QLOG_EVENT_TYPE_##e_cat##_##e_name, add); +# include "internal/qlog_events.h" +# undef QLOG_EVENT +} + +static int lex_fail(struct lexer *lex, const char *msg) +{ + /* + * TODO(QLOG FUTURE): Determine how to print log messages about bad filter + * strings + */ + lex->p = lex->term_end = lex->end; + return 0; +} + +static int validate_name(const char **p, size_t *l) +{ + const char *p_ = *p; + size_t i, l_ = *l; + + if (l_ == 1 && *p_ == '*') { + *p = NULL; + *l = 0; + return 1; + } + + if (l_ == 0) + return 0; + + for (i = 0; i < l_; ++i) + if (!is_name_char(p_[i])) + return 0; + + return 1; +} + +int ossl_qlog_set_filter(QLOG *qlog, const char *filter) +{ + struct lexer lex = {0}; + char c; + const char *cat, *event; + size_t cat_l, event_l, enabled[NUM_ENABLED_W]; + int add; + + memcpy(enabled, qlog->enabled, sizeof(enabled)); + + if (!lex_init(&lex, filter, strlen(filter))) + return 0; + + while (lex_do(&lex)) { + c = lex_peek_char(&lex); + if (c == '+' || c == '-') { + add = (c == '+'); + lex_skip_char(&lex); + + c = lex_peek_char(&lex); + if (!is_name_char(c) && c != '*') + return lex_fail(&lex, "expected alphanumeric name or '*'" + " after +/-"); + } else if (!is_name_char(c) && c != '*') { + return lex_fail(&lex, "expected +/- or alphanumeric name or '*'"); + } else { + add = 1; + } + + if (lex_match(&lex, "*", 1)) { + filter_apply(enabled, add, NULL, 0, NULL, 0); + continue; + } + + if (!lex_extract_to(&lex, ':', &cat, &cat_l)) + return lex_fail(&lex, "expected ':' after category name"); + + lex_get_rest(&lex, &event, &event_l); + if (!validate_name(&cat, &cat_l)) + return lex_fail(&lex, "expected alphanumeric category name or '*'"); + if (!validate_name(&event, &event_l)) + return lex_fail(&lex, "expected alphanumeric event name or '*'"); + + filter_apply(enabled, add, cat, cat_l, event, event_l); + } + + memcpy(qlog->enabled, enabled, sizeof(enabled)); + return 1; +} diff --git a/libs/openssl-3/ssl/quic/qlog_event_helpers.c b/libs/openssl-3/ssl/quic/qlog_event_helpers.c new file mode 100644 index 000000000..55cc28d9f --- /dev/null +++ b/libs/openssl-3/ssl/quic/qlog_event_helpers.c @@ -0,0 +1,634 @@ +/* + * 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 + */ + +#include "internal/qlog_event_helpers.h" +#include "internal/common.h" +#include "internal/packet.h" +#include "internal/quic_channel.h" +#include "internal/quic_error.h" + +void ossl_qlog_event_connectivity_connection_started(QLOG *qlog, + const QUIC_CONN_ID *init_dcid) +{ +#ifndef OPENSSL_NO_QLOG + QLOG_EVENT_BEGIN(qlog, connectivity, connection_started) + QLOG_STR("protocol", "quic"); + QLOG_CID("dst_cid", init_dcid); + QLOG_EVENT_END() +#endif +} + +#ifndef OPENSSL_NO_QLOG +static const char *map_state_to_qlog(uint32_t state, + int handshake_complete, + int handshake_confirmed) +{ + switch (state) { + default: + case QUIC_CHANNEL_STATE_IDLE: + return NULL; + + case QUIC_CHANNEL_STATE_ACTIVE: + if (handshake_confirmed) + return "handshake_confirmed"; + else if (handshake_complete) + return "handshake_complete"; + else + return "attempted"; + + case QUIC_CHANNEL_STATE_TERMINATING_CLOSING: + return "closing"; + + case QUIC_CHANNEL_STATE_TERMINATING_DRAINING: + return "draining"; + + case QUIC_CHANNEL_STATE_TERMINATED: + return "closed"; + } +} +#endif + +void ossl_qlog_event_connectivity_connection_state_updated(QLOG *qlog, + uint32_t old_state, + uint32_t new_state, + int handshake_complete, + int handshake_confirmed) +{ +#ifndef OPENSSL_NO_QLOG + const char *state_s; + + QLOG_EVENT_BEGIN(qlog, connectivity, connection_state_updated) + state_s = map_state_to_qlog(new_state, + handshake_complete, + handshake_confirmed); + + if (state_s != NULL) + QLOG_STR("state", state_s); + QLOG_EVENT_END() +#endif +} + +#ifndef OPENSSL_NO_QLOG +static const char *quic_err_to_qlog(uint64_t error_code) +{ + switch (error_code) { + case OSSL_QUIC_ERR_INTERNAL_ERROR: + return "internal_error"; + case OSSL_QUIC_ERR_CONNECTION_REFUSED: + return "connection_refused"; + case OSSL_QUIC_ERR_FLOW_CONTROL_ERROR: + return "flow_control_error"; + case OSSL_QUIC_ERR_STREAM_LIMIT_ERROR: + return "stream_limit_error"; + case OSSL_QUIC_ERR_STREAM_STATE_ERROR: + return "stream_state_error"; + case OSSL_QUIC_ERR_FINAL_SIZE_ERROR: + return "final_size_error"; + case OSSL_QUIC_ERR_FRAME_ENCODING_ERROR: + return "frame_encoding_error"; + case OSSL_QUIC_ERR_TRANSPORT_PARAMETER_ERROR: + return "transport_parameter_error"; + case OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR: + return "connection_id_limit_error"; + case OSSL_QUIC_ERR_PROTOCOL_VIOLATION: + return "protocol_violation"; + case OSSL_QUIC_ERR_INVALID_TOKEN: + return "invalid_token"; + case OSSL_QUIC_ERR_APPLICATION_ERROR: + return "application_error"; + case OSSL_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED: + return "crypto_buffer_exceeded"; + case OSSL_QUIC_ERR_KEY_UPDATE_ERROR: + return "key_update_error"; + case OSSL_QUIC_ERR_AEAD_LIMIT_REACHED: + return "aead_limit_reached"; + case OSSL_QUIC_ERR_NO_VIABLE_PATH: + return "no_viable_path"; + default: + return NULL; + } +} +#endif + +void ossl_qlog_event_connectivity_connection_closed(QLOG *qlog, + const QUIC_TERMINATE_CAUSE *tcause) +{ +#ifndef OPENSSL_NO_QLOG + QLOG_EVENT_BEGIN(qlog, connectivity, connection_closed) + QLOG_STR("owner", tcause->remote ? "remote" : "local"); + if (tcause->app) { + QLOG_U64("application_code", tcause->error_code); + } else { + const char *m = quic_err_to_qlog(tcause->error_code); + char ce[32]; + + if (tcause->error_code >= OSSL_QUIC_ERR_CRYPTO_ERR_BEGIN + && tcause->error_code <= OSSL_QUIC_ERR_CRYPTO_ERR_END) { + BIO_snprintf(ce, sizeof(ce), "crypto_error_0x%03llx", + (unsigned long long)tcause->error_code); + m = ce; + } + /* TODO(QLOG FUTURE): Consider adding ERR information in the output. */ + + if (m != NULL) + QLOG_STR("connection_code", m); + else + QLOG_U64("connection_code", tcause->error_code); + } + + QLOG_STR_LEN("reason", tcause->reason, tcause->reason_len); + QLOG_EVENT_END() +#endif +} + +#ifndef OPENSSL_NO_QLOG +static const char *quic_pkt_type_to_qlog(uint32_t pkt_type) +{ + switch (pkt_type) { + case QUIC_PKT_TYPE_INITIAL: + return "initial"; + case QUIC_PKT_TYPE_HANDSHAKE: + return "handshake"; + case QUIC_PKT_TYPE_0RTT: + return "0RTT"; + case QUIC_PKT_TYPE_1RTT: + return "1RTT"; + case QUIC_PKT_TYPE_VERSION_NEG: + return "version_negotiation"; + case QUIC_PKT_TYPE_RETRY: + return "retry"; + default: + return "unknown"; + } +} +#endif + +void ossl_qlog_event_recovery_packet_lost(QLOG *qlog, + const QUIC_TXPIM_PKT *tpkt) +{ +#ifndef OPENSSL_NO_QLOG + QLOG_EVENT_BEGIN(qlog, recovery, packet_lost) + QLOG_BEGIN("header") + QLOG_STR("packet_type", quic_pkt_type_to_qlog(tpkt->pkt_type)); + if (ossl_quic_pkt_type_has_pn(tpkt->pkt_type)) + QLOG_U64("packet_number", tpkt->ackm_pkt.pkt_num); + QLOG_END() + QLOG_EVENT_END() +#endif +} + +#ifndef OPENSSL_NO_QLOG +# define MAX_ACK_RANGES 32 + +static void ignore_res(int x) {} + +/* + * For logging received packets, we need to parse all the frames in the packet + * to log them. We should do this separately to the RXDP code because we want to + * log the packet and its contents before we start to actually process it in + * case it causes an error. We also in general don't want to do other + * non-logging related work in the middle of an event logging transaction. + * Reparsing packet data allows us to meet these needs while avoiding the need + * to keep around bookkeeping data on what frames were in a packet, etc. + * + * For logging transmitted packets, we actually reuse the same code and reparse + * the outgoing packet's payload. This again has the advantage that we only log + * a packet when it is actually queued for transmission (and not if something + * goes wrong before then) while avoiding the need to keep around bookkeeping + * data on what frames it contained. + */ +static int log_frame_actual(QLOG *qlog_instance, PACKET *pkt, + size_t *need_skip) +{ + uint64_t frame_type; + OSSL_QUIC_FRAME_ACK ack; + OSSL_QUIC_ACK_RANGE ack_ranges[MAX_ACK_RANGES]; + uint64_t num_ranges, total_ranges; + size_t i; + PACKET orig_pkt = *pkt; + + if (!ossl_quic_wire_peek_frame_header(pkt, &frame_type, NULL)) + return 0; + + /* + * If something goes wrong decoding a frame we cannot log it as that frame + * as we need to know how to decode it in order to be able to do so, but in + * that case we log it as an unknown frame to assist with diagnosis. + */ + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_PADDING: + QLOG_STR("frame_type", "padding"); + QLOG_U64("payload_length", + ossl_quic_wire_decode_padding(pkt)); + break; + case OSSL_QUIC_FRAME_TYPE_PING: + if (!ossl_quic_wire_decode_frame_ping(pkt)) + goto unknown; + + QLOG_STR("frame_type", "ping"); + break; + case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN: + case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: + if (!ossl_quic_wire_peek_frame_ack_num_ranges(pkt, &num_ranges)) + goto unknown; + + ack.ack_ranges = ack_ranges; + ack.num_ack_ranges = OSSL_NELEM(ack_ranges); + if (!ossl_quic_wire_decode_frame_ack(pkt, 3, &ack, &total_ranges)) + goto unknown; + + QLOG_STR("frame_type", "ack"); + QLOG_U64("ack_delay", ossl_time2ms(ack.delay_time)); + if (ack.ecn_present) { + QLOG_U64("ect1", ack.ect0); + QLOG_U64("ect0", ack.ect1); + QLOG_U64("ce", ack.ecnce); + } + QLOG_BEGIN_ARRAY("acked_ranges"); + for (i = 0; i < ack.num_ack_ranges; ++i) { + QLOG_BEGIN_ARRAY(NULL) + QLOG_U64(NULL, ack.ack_ranges[i].start); + if (ack.ack_ranges[i].end != ack.ack_ranges[i].start) + QLOG_U64(NULL, ack.ack_ranges[i].end); + QLOG_END_ARRAY() + } + QLOG_END_ARRAY() + break; + case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: + { + OSSL_QUIC_FRAME_RESET_STREAM f; + + if (!ossl_quic_wire_decode_frame_reset_stream(pkt, &f)) + goto unknown; + + QLOG_STR("frame_type", "reset_stream"); + QLOG_U64("stream_id", f.stream_id); + QLOG_U64("error_code", f.app_error_code); + QLOG_U64("final_size", f.final_size); + } + break; + case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: + { + OSSL_QUIC_FRAME_STOP_SENDING f; + + if (!ossl_quic_wire_decode_frame_stop_sending(pkt, &f)) + goto unknown; + + QLOG_STR("frame_type", "stop_sending"); + QLOG_U64("stream_id", f.stream_id); + QLOG_U64("error_code", f.app_error_code); + } + break; + case OSSL_QUIC_FRAME_TYPE_CRYPTO: + { + OSSL_QUIC_FRAME_CRYPTO f; + + if (!ossl_quic_wire_decode_frame_crypto(pkt, 1, &f)) + goto unknown; + + QLOG_STR("frame_type", "crypto"); + QLOG_U64("offset", f.offset); + QLOG_U64("payload_length", f.len); + *need_skip += (size_t)f.len; + } + break; + case OSSL_QUIC_FRAME_TYPE_STREAM: + case OSSL_QUIC_FRAME_TYPE_STREAM_FIN: + case OSSL_QUIC_FRAME_TYPE_STREAM_LEN: + case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN: + { + OSSL_QUIC_FRAME_STREAM f; + + if (!ossl_quic_wire_decode_frame_stream(pkt, 1, &f)) + goto unknown; + + QLOG_STR("frame_type", "stream"); + QLOG_U64("stream_id", f.stream_id); + QLOG_U64("offset", f.offset); + QLOG_U64("payload_length", f.len); + QLOG_BOOL("explicit_length", f.has_explicit_len); + if (f.is_fin) + QLOG_BOOL("fin", 1); + *need_skip = f.has_explicit_len + ? *need_skip + (size_t)f.len : SIZE_MAX; + } + break; + case OSSL_QUIC_FRAME_TYPE_MAX_DATA: + { + uint64_t x; + + if (!ossl_quic_wire_decode_frame_max_data(pkt, &x)) + goto unknown; + + QLOG_STR("frame_type", "max_data"); + QLOG_U64("maximum", x); + } + break; + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI: + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: + { + uint64_t x; + + if (!ossl_quic_wire_decode_frame_max_streams(pkt, &x)) + goto unknown; + + QLOG_STR("frame_type", "max_streams"); + QLOG_STR("stream_type", + frame_type == OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI + ? "bidirectional" : "unidirectional"); + QLOG_U64("maximum", x); + } + break; + case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA: + { + uint64_t stream_id, max_data; + + if (!ossl_quic_wire_decode_frame_max_stream_data(pkt, &stream_id, + &max_data)) + goto unknown; + + QLOG_STR("frame_type", "max_stream_data"); + QLOG_U64("stream_id", stream_id); + QLOG_U64("maximum", max_data); + } + break; + case OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE: + { + uint64_t challenge; + + if (!ossl_quic_wire_decode_frame_path_challenge(pkt, &challenge)) + goto unknown; + + QLOG_STR("frame_type", "path_challenge"); + } + break; + case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: + { + uint64_t challenge; + + if (!ossl_quic_wire_decode_frame_path_response(pkt, &challenge)) + goto unknown; + + QLOG_STR("frame_type", "path_response"); + } + break; + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP: + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT: + { + OSSL_QUIC_FRAME_CONN_CLOSE f; + + if (!ossl_quic_wire_decode_frame_conn_close(pkt, &f)) + goto unknown; + + QLOG_STR("frame_type", "connection_close"); + QLOG_STR("error_space", f.is_app ? "application" : "transport"); + QLOG_U64("error_code_value", f.error_code); + if (f.is_app) + QLOG_U64("error_code", f.error_code); + if (!f.is_app && f.frame_type != 0) + QLOG_U64("trigger_frame_type", f.frame_type); + QLOG_STR_LEN("reason", f.reason, f.reason_len); + } + break; + case OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE: + { + if (!ossl_quic_wire_decode_frame_handshake_done(pkt)) + goto unknown; + + QLOG_STR("frame_type", "handshake_done"); + } + break; + case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: + { + OSSL_QUIC_FRAME_NEW_CONN_ID f; + + if (!ossl_quic_wire_decode_frame_new_conn_id(pkt, &f)) + goto unknown; + + QLOG_STR("frame_type", "new_connection_id"); + QLOG_U64("sequence_number", f.seq_num); + QLOG_U64("retire_prior_to", f.retire_prior_to); + QLOG_CID("connection_id", &f.conn_id); + QLOG_BIN("stateless_reset_token", + f.stateless_reset.token, + sizeof(f.stateless_reset.token)); + } + break; + case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: + { + uint64_t seq_num; + + if (!ossl_quic_wire_decode_frame_retire_conn_id(pkt, &seq_num)) + goto unknown; + + QLOG_STR("frame_type", "retire_connection_id"); + QLOG_U64("sequence_number", seq_num); + } + break; + case OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED: + { + uint64_t x; + + if (!ossl_quic_wire_decode_frame_data_blocked(pkt, &x)) + goto unknown; + + QLOG_STR("frame_type", "data_blocked"); + QLOG_U64("limit", x); + } + break; + case OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED: + { + uint64_t stream_id, x; + + if (!ossl_quic_wire_decode_frame_stream_data_blocked(pkt, + &stream_id, + &x)) + goto unknown; + + QLOG_STR("frame_type", "stream_data_blocked"); + QLOG_U64("stream_id", stream_id); + QLOG_U64("limit", x); + } + break; + case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI: + case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI: + { + uint64_t x; + + if (!ossl_quic_wire_decode_frame_streams_blocked(pkt, &x)) + goto unknown; + + QLOG_STR("frame_type", "streams_blocked"); + QLOG_STR("stream_type", + frame_type == OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI + ? "bidirectional" : "unidirectional"); + QLOG_U64("limit", x); + } + break; + case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: + { + const unsigned char *token; + size_t token_len; + + if (!ossl_quic_wire_decode_frame_new_token(pkt, &token, &token_len)) + goto unknown; + + QLOG_STR("frame_type", "new_token"); + QLOG_BEGIN("token"); + QLOG_BEGIN("raw"); + QLOG_BIN("data", token, token_len); + QLOG_END(); + QLOG_END(); + } + break; + default: +unknown: + QLOG_STR("frame_type", "unknown"); + QLOG_U64("frame_type_value", frame_type); + + /* + * Can't continue scanning for frames in this case as the frame length + * is unknown. We log the entire body of the rest of the packet payload + * as the raw data of the frame. + */ + QLOG_BEGIN("raw"); + QLOG_BIN("data", PACKET_data(&orig_pkt), + PACKET_remaining(&orig_pkt)); + QLOG_END(); + ignore_res(PACKET_forward(pkt, PACKET_remaining(pkt))); + break; + } + + return 1; +} + +static void log_frame(QLOG *qlog_instance, PACKET *pkt, + size_t *need_skip) +{ + size_t rem_before, rem_after; + + rem_before = PACKET_remaining(pkt); + + if (!log_frame_actual(qlog_instance, pkt, need_skip)) + return; + + rem_after = PACKET_remaining(pkt); + QLOG_U64("length", rem_before - rem_after); +} + +static int log_frames(QLOG *qlog_instance, + const OSSL_QTX_IOVEC *iovec, + size_t num_iovec) +{ + size_t i; + PACKET pkt; + size_t need_skip = 0; + + for (i = 0; i < num_iovec; ++i) { + if (!PACKET_buf_init(&pkt, iovec[i].buf, iovec[i].buf_len)) + return 0; + + while (PACKET_remaining(&pkt) > 0) { + if (need_skip > 0) { + size_t adv = need_skip; + + if (adv < PACKET_remaining(&pkt)) + adv = PACKET_remaining(&pkt); + + if (!PACKET_forward(&pkt, adv)) + return 0; + + need_skip -= adv; + continue; + } + + QLOG_BEGIN(NULL) + { + log_frame(qlog_instance, &pkt, &need_skip); + } + QLOG_END() + } + } + + return 1; +} + +static void log_packet(QLOG *qlog_instance, + const QUIC_PKT_HDR *hdr, + QUIC_PN pn, + const OSSL_QTX_IOVEC *iovec, + size_t num_iovec, + uint64_t datagram_id) +{ + const char *type_s; + + QLOG_BEGIN("header") + type_s = quic_pkt_type_to_qlog(hdr->type); + if (type_s == NULL) + type_s = "unknown"; + + QLOG_STR("packet_type", type_s); + if (ossl_quic_pkt_type_has_pn(hdr->type)) + QLOG_U64("packet_number", pn); + + QLOG_CID("dcid", &hdr->dst_conn_id); + if (ossl_quic_pkt_type_has_scid(hdr->type)) + QLOG_CID("scid", &hdr->src_conn_id); + + if (hdr->token_len > 0) { + QLOG_BEGIN("token") + QLOG_BEGIN("raw") + QLOG_BIN("data", hdr->token, hdr->token_len); + QLOG_END() + QLOG_END() + } + /* TODO(QLOG FUTURE): flags, length */ + QLOG_END() + QLOG_U64("datagram_id", datagram_id); + + if (ossl_quic_pkt_type_is_encrypted(hdr->type)) { + QLOG_BEGIN_ARRAY("frames") + log_frames(qlog_instance, iovec, num_iovec); + QLOG_END_ARRAY() + } +} + +#endif + +void ossl_qlog_event_transport_packet_sent(QLOG *qlog, + const QUIC_PKT_HDR *hdr, + QUIC_PN pn, + const OSSL_QTX_IOVEC *iovec, + size_t num_iovec, + uint64_t datagram_id) +{ +#ifndef OPENSSL_NO_QLOG + QLOG_EVENT_BEGIN(qlog, transport, packet_sent) + log_packet(qlog, hdr, pn, iovec, num_iovec, datagram_id); + QLOG_EVENT_END() +#endif +} + +void ossl_qlog_event_transport_packet_received(QLOG *qlog, + const QUIC_PKT_HDR *hdr, + QUIC_PN pn, + const OSSL_QTX_IOVEC *iovec, + size_t num_iovec, + uint64_t datagram_id) +{ +#ifndef OPENSSL_NO_QLOG + QLOG_EVENT_BEGIN(qlog, transport, packet_received) + log_packet(qlog, hdr, pn, iovec, num_iovec, datagram_id); + QLOG_EVENT_END() +#endif +} diff --git a/libs/openssl-3/ssl/quic/quic_channel.c b/libs/openssl-3/ssl/quic/quic_channel.c index d3b7947fb..396cbe846 100644 --- a/libs/openssl-3/ssl/quic/quic_channel.c +++ b/libs/openssl-3/ssl/quic/quic_channel.c @@ -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,8 +12,13 @@ #include "internal/quic_channel.h" #include "internal/quic_error.h" #include "internal/quic_rx_depack.h" +#include "internal/quic_lcidm.h" +#include "internal/quic_srtm.h" +#include "internal/qlog_event_helpers.h" #include "../ssl_local.h" #include "quic_channel_local.h" +#include "quic_port_local.h" +#include "quic_engine_local.h" /* * NOTE: While this channel implementation currently has basic server support, @@ -25,7 +30,6 @@ * TODO(QUIC SERVER): Implement retry logic */ -#define INIT_DCID_LEN 8 #define INIT_CRYPTO_RECV_BUF_LEN 16384 #define INIT_CRYPTO_SEND_BUF_LEN 16384 #define INIT_APP_BUF_LEN 8192 @@ -45,11 +49,11 @@ */ #define DEFAULT_MAX_ACK_DELAY QUIC_DEFAULT_MAX_ACK_DELAY +DEFINE_LIST_OF_IMPL(ch, QUIC_CHANNEL); + static void ch_save_err_state(QUIC_CHANNEL *ch); -static void ch_rx_pre(QUIC_CHANNEL *ch); static int ch_rx(QUIC_CHANNEL *ch, int channel_only); static int ch_tx(QUIC_CHANNEL *ch); -static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags); static int ch_tick_tls(QUIC_CHANNEL *ch, int channel_only); static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only); static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch); @@ -89,168 +93,57 @@ static int ch_discard_el(QUIC_CHANNEL *ch, static void ch_on_idle_timeout(QUIC_CHANNEL *ch); static void ch_update_idle(QUIC_CHANNEL *ch); static void ch_update_ping_deadline(QUIC_CHANNEL *ch); -static void ch_stateless_reset(QUIC_CHANNEL *ch); -static void ch_raise_net_error(QUIC_CHANNEL *ch); static void ch_on_terminating_timeout(QUIC_CHANNEL *ch); static void ch_start_terminating(QUIC_CHANNEL *ch, const QUIC_TERMINATE_CAUSE *tcause, int force_immediate); -static int ch_stateless_reset_token_handler(const unsigned char *data, size_t datalen, void *arg); -static void ch_default_packet_handler(QUIC_URXE *e, void *arg); -static int ch_server_on_new_conn(QUIC_CHANNEL *ch, const BIO_ADDR *peer, - const QUIC_CONN_ID *peer_scid, - const QUIC_CONN_ID *peer_dcid); static void ch_on_txp_ack_tx(const OSSL_QUIC_FRAME_ACK *ack, uint32_t pn_space, void *arg); static void ch_rx_handle_version_neg(QUIC_CHANNEL *ch, OSSL_QRX_PKT *pkt); static void ch_raise_version_neg_failure(QUIC_CHANNEL *ch); +static void ch_record_state_transition(QUIC_CHANNEL *ch, uint32_t new_state); DEFINE_LHASH_OF_EX(QUIC_SRT_ELEM); -static int gen_rand_conn_id(OSSL_LIB_CTX *libctx, size_t len, QUIC_CONN_ID *cid) -{ - if (len > QUIC_MAX_CONN_ID_LEN) - return 0; - - cid->id_len = (unsigned char)len; - - if (RAND_bytes_ex(libctx, cid->id, len, len * 8) != 1) { - ERR_raise(ERR_LIB_SSL, ERR_R_RAND_LIB); - cid->id_len = 0; - return 0; - } - - return 1; -} - -static unsigned long chan_reset_token_hash(const QUIC_SRT_ELEM *a) -{ - unsigned long h; - - assert(sizeof(h) <= sizeof(a->token)); - memcpy(&h, &a->token, sizeof(h)); - return h; -} - -static int chan_reset_token_cmp(const QUIC_SRT_ELEM *a, const QUIC_SRT_ELEM *b) -{ - /* RFC 9000 s. 10.3.1: - * When comparing a datagram to stateless reset token values, - * endpoints MUST perform the comparison without leaking - * information about the value of the token. For example, - * performing this comparison in constant time protects the - * value of individual stateless reset tokens from information - * leakage through timing side channels. - * - * TODO(QUIC FUTURE): make this a memcmp when obfuscation is done and update - * comment above. - */ - return CRYPTO_memcmp(&a->token, &b->token, sizeof(a->token)); -} - -static int reset_token_obfuscate(QUIC_SRT_ELEM *out, const unsigned char *in) +QUIC_NEEDS_LOCK +static QLOG *ch_get_qlog(QUIC_CHANNEL *ch) { - /* - * TODO(QUIC FUTURE): update this to AES encrypt the token in ECB mode with a - * random (per channel) key. - */ - memcpy(&out->token, in, sizeof(out->token)); - return 1; -} +#ifndef OPENSSL_NO_QLOG + QLOG_TRACE_INFO qti = {0}; -/* - * Add a stateless reset token to the channel - */ -static int chan_add_reset_token(QUIC_CHANNEL *ch, const unsigned char *new, - uint64_t seq_num) -{ - QUIC_SRT_ELEM *srte; - int err; + if (ch->qlog != NULL) + return ch->qlog; - /* Add to list by sequence number (always the tail) */ - if ((srte = OPENSSL_malloc(sizeof(*srte))) == NULL) - return 0; + if (!ch->use_qlog) + return NULL; - ossl_list_stateless_reset_tokens_init_elem(srte); - ossl_list_stateless_reset_tokens_insert_tail(&ch->srt_list_seq, srte); - reset_token_obfuscate(srte, new); - srte->seq_num = seq_num; + if (ch->is_server && ch->init_dcid.id_len == 0) + return NULL; - lh_QUIC_SRT_ELEM_insert(ch->srt_hash_tok, srte); - err = lh_QUIC_SRT_ELEM_error(ch->srt_hash_tok); - if (err > 0) { - ossl_list_stateless_reset_tokens_remove(&ch->srt_list_seq, srte); - OPENSSL_free(srte); - return 0; + qti.odcid = ch->init_dcid; + qti.title = ch->qlog_title; + qti.description = NULL; + qti.group_id = NULL; + qti.is_server = ch->is_server; + qti.now_cb = get_time; + qti.now_cb_arg = ch; + if ((ch->qlog = ossl_qlog_new_from_env(&qti)) == NULL) { + ch->use_qlog = 0; /* don't try again */ + return NULL; } - return 1; -} -/* - * Remove a stateless reset token from the channel - * If the token isn't known, we just ignore the remove request which is safe. - */ -static void chan_remove_reset_token(QUIC_CHANNEL *ch, uint64_t seq_num) -{ - QUIC_SRT_ELEM *srte; - - /* - * Because the list is ordered and we only ever remove CIDs in order, - * this loop should never iterate, but safer to provide the option. - */ - for (srte = ossl_list_stateless_reset_tokens_head(&ch->srt_list_seq); - srte != NULL; - srte = ossl_list_stateless_reset_tokens_next(srte)) { - if (srte->seq_num > seq_num) - return; - if (srte->seq_num == seq_num) { - ossl_list_stateless_reset_tokens_remove(&ch->srt_list_seq, srte); - (void)lh_QUIC_SRT_ELEM_delete(ch->srt_hash_tok, srte); - OPENSSL_free(srte); - return; - } - } + return ch->qlog; +#else + return NULL; +#endif } -/* - * This is called by the demux whenever a new datagram arrives - * - * TODO(QUIC FUTURE): optimise this to only be called for unparsable packets - */ -static int ch_stateless_reset_token_handler(const unsigned char *data, - size_t datalen, void *arg) +QUIC_NEEDS_LOCK +static QLOG *ch_get_qlog_cb(void *arg) { - QUIC_SRT_ELEM srte; - QUIC_CHANNEL *ch = (QUIC_CHANNEL *)arg; + QUIC_CHANNEL *ch = arg; - /* - * Perform some fast and cheap checks for a packet not being a stateless - * reset token. RFC 9000 s. 10.3 specifies this layout for stateless - * reset packets: - * - * Stateless Reset { - * Fixed Bits (2) = 1, - * Unpredictable Bits (38..), - * Stateless Reset Token (128), - * } - * - * It also specifies: - * However, endpoints MUST treat any packet ending in a valid - * stateless reset token as a Stateless Reset, as other QUIC - * versions might allow the use of a long header. - * - * We can rapidly check for the minimum length and that the first pair - * of bits in the first byte are 01 or 11. - * - * The function returns 1 if it is a stateless reset packet, 0 if it isn't - * and -1 if an error was encountered. - */ - if (datalen < QUIC_STATELESS_RESET_TOKEN_LEN + 5 || (0100 & *data) != 0100) - return 0; - memset(&srte, 0, sizeof(srte)); - if (!reset_token_obfuscate(&srte, data + datalen - sizeof(srte.token))) - return -1; - return lh_QUIC_SRT_ELEM_retrieve(ch->srt_hash_tok, &srte) != NULL; + return ch_get_qlog(ch); } /* @@ -272,22 +165,26 @@ static int ch_init(QUIC_CHANNEL *ch) OSSL_QRX_ARGS qrx_args = {0}; QUIC_TLS_ARGS tls_args = {0}; uint32_t pn_space; - size_t rx_short_cid_len = ch->is_server ? INIT_DCID_LEN : 0; + size_t rx_short_dcid_len; + size_t tx_init_dcid_len; - ossl_list_stateless_reset_tokens_init(&ch->srt_list_seq); - ch->srt_hash_tok = lh_QUIC_SRT_ELEM_new(&chan_reset_token_hash, - &chan_reset_token_cmp); - if (ch->srt_hash_tok == NULL) + if (ch->port == NULL || ch->lcidm == NULL || ch->srtm == NULL) goto err; + rx_short_dcid_len = ossl_quic_port_get_rx_short_dcid_len(ch->port); + tx_init_dcid_len = ossl_quic_port_get_tx_init_dcid_len(ch->port); + /* For clients, generate our initial DCID. */ if (!ch->is_server - && !gen_rand_conn_id(ch->libctx, INIT_DCID_LEN, &ch->init_dcid)) + && !ossl_quic_gen_rand_conn_id(ch->port->engine->libctx, tx_init_dcid_len, + &ch->init_dcid)) goto err; /* We plug in a network write BIO to the QTX later when we get one. */ - qtx_args.libctx = ch->libctx; - qtx_args.mdpl = QUIC_MIN_INITIAL_DGRAM_LEN; + qtx_args.libctx = ch->port->engine->libctx; + qtx_args.get_qlog_cb = ch_get_qlog_cb; + qtx_args.get_qlog_cb_arg = ch; + qtx_args.mdpl = QUIC_MIN_INITIAL_DGRAM_LEN; ch->rx_max_udp_payload_size = qtx_args.mdpl; ch->ping_deadline = ossl_time_infinite(); @@ -358,6 +255,10 @@ static int ch_init(QUIC_CHANNEL *ch) ch->have_qsm = 1; + if (!ch->is_server + && !ossl_quic_lcidm_generate_initial(ch->lcidm, ch, &txp_args.cur_scid)) + goto err; + /* We use a zero-length SCID. */ txp_args.cur_dcid = ch->init_dcid; txp_args.ack_delay_exponent = 3; @@ -374,6 +275,8 @@ static int ch_init(QUIC_CHANNEL *ch) txp_args.cc_data = ch->cc_data; txp_args.now = get_time; txp_args.now_arg = ch; + txp_args.get_qlog_cb = ch_get_qlog_cb; + txp_args.get_qlog_cb_arg = ch; for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) { ch->crypto_send[pn_space] = ossl_quic_sstream_new(INIT_CRYPTO_SEND_BUF_LEN); @@ -389,31 +292,9 @@ static int ch_init(QUIC_CHANNEL *ch) ossl_quic_tx_packetiser_set_ack_tx_cb(ch->txp, ch_on_txp_ack_tx, ch); - if ((ch->demux = ossl_quic_demux_new(/*BIO=*/NULL, - /*Short CID Len=*/rx_short_cid_len, - get_time, ch)) == NULL) - goto err; - - /* - * Setup a handler to detect stateless reset tokens. - */ - ossl_quic_demux_set_stateless_reset_handler(ch->demux, - &ch_stateless_reset_token_handler, - ch); - - /* - * If we are a server, setup our handler for packets not corresponding to - * any known DCID on our end. This is for handling clients establishing new - * connections. - */ - if (ch->is_server) - ossl_quic_demux_set_default_handler(ch->demux, - ch_default_packet_handler, - ch); - - qrx_args.libctx = ch->libctx; - qrx_args.demux = ch->demux; - qrx_args.short_conn_id_len = rx_short_cid_len; + qrx_args.libctx = ch->port->engine->libctx; + qrx_args.demux = ch->port->demux; + qrx_args.short_conn_id_len = rx_short_dcid_len; qrx_args.max_deferred = 32; if ((ch->qrx = ossl_qrx_new(&qrx_args)) == NULL) @@ -429,9 +310,6 @@ static int ch_init(QUIC_CHANNEL *ch) ch)) goto err; - if (!ch->is_server && !ossl_qrx_add_dst_conn_id(ch->qrx, &txp_args.cur_scid)) - goto err; - for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) { ch->crypto_recv[pn_space] = ossl_quic_rstream_new(NULL, NULL, 0); if (ch->crypto_recv[pn_space] == NULL) @@ -463,25 +341,20 @@ static int ch_init(QUIC_CHANNEL *ch) ch->rx_max_ack_delay = QUIC_DEFAULT_MAX_ACK_DELAY; ch->rx_ack_delay_exp = QUIC_DEFAULT_ACK_DELAY_EXP; ch->rx_active_conn_id_limit = QUIC_MIN_ACTIVE_CONN_ID_LIMIT; - ch->max_idle_timeout = QUIC_DEFAULT_IDLE_TIMEOUT; ch->tx_enc_level = QUIC_ENC_LEVEL_INITIAL; ch->rx_enc_level = QUIC_ENC_LEVEL_INITIAL; ch->txku_threshold_override = UINT64_MAX; + ch->max_idle_timeout_local_req = QUIC_DEFAULT_IDLE_TIMEOUT; + ch->max_idle_timeout_remote_req = 0; + ch->max_idle_timeout = ch->max_idle_timeout_local_req; + ossl_ackm_set_tx_max_ack_delay(ch->ackm, ossl_ms2time(ch->tx_max_ack_delay)); ossl_ackm_set_rx_max_ack_delay(ch->ackm, ossl_ms2time(ch->rx_max_ack_delay)); - /* - * Determine the QUIC Transport Parameters and serialize the transport - * parameters block. (For servers, we do this later as we must defer - * generation until we have received the client's transport parameters.) - */ - if (!ch->is_server && !ch_generate_transport_params(ch)) - goto err; - ch_update_idle(ch); - ossl_quic_reactor_init(&ch->rtor, ch_tick, ch, - ch_determine_next_tick_deadline(ch)); + ossl_list_ch_insert_tail(&ch->port->channel_list, ch); + ch->on_port_list = 1; return 1; err: @@ -491,7 +364,6 @@ static int ch_init(QUIC_CHANNEL *ch) static void ch_cleanup(QUIC_CHANNEL *ch) { - QUIC_SRT_ELEM *srte, *srte_next; uint32_t pn_space; if (ch->ackm != NULL) @@ -500,6 +372,8 @@ static void ch_cleanup(QUIC_CHANNEL *ch) ++pn_space) ossl_ackm_on_pkt_space_discarded(ch->ackm, pn_space); + ossl_quic_lcidm_cull(ch->lcidm, ch); + ossl_quic_srtm_cull(ch->srtm, ch); ossl_quic_tx_packetiser_free(ch->txp); ossl_quic_txpim_free(ch->txpim); ossl_quic_cfq_free(ch->cfq); @@ -523,22 +397,23 @@ static void ch_cleanup(QUIC_CHANNEL *ch) ossl_quic_tls_free(ch->qtls); ossl_qrx_free(ch->qrx); - ossl_quic_demux_free(ch->demux); OPENSSL_free(ch->local_transport_params); OPENSSL_free((char *)ch->terminate_cause.reason); OSSL_ERR_STATE_free(ch->err_state); OPENSSL_free(ch->ack_range_scratch); - /* Free the stateless reset tokens */ - for (srte = ossl_list_stateless_reset_tokens_head(&ch->srt_list_seq); - srte != NULL; - srte = srte_next) { - srte_next = ossl_list_stateless_reset_tokens_next(srte); - ossl_list_stateless_reset_tokens_remove(&ch->srt_list_seq, srte); - (void)lh_QUIC_SRT_ELEM_delete(ch->srt_hash_tok, srte); - OPENSSL_free(srte); + if (ch->on_port_list) { + ossl_list_ch_remove(&ch->port->channel_list, ch); + ch->on_port_list = 0; } - lh_QUIC_SRT_ELEM_free(ch->srt_hash_tok); + +#ifndef OPENSSL_NO_QLOG + if (ch->qlog != NULL) + ossl_qlog_flush(ch->qlog); /* best effort */ + + OPENSSL_free(ch->qlog_title); + ossl_qlog_free(ch->qlog); +#endif } QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args) @@ -548,13 +423,21 @@ QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args) if ((ch = OPENSSL_zalloc(sizeof(*ch))) == NULL) return NULL; - ch->libctx = args->libctx; - ch->propq = args->propq; + ch->port = args->port; ch->is_server = args->is_server; ch->tls = args->tls; - ch->mutex = args->mutex; - ch->now_cb = args->now_cb; - ch->now_cb_arg = args->now_cb_arg; + ch->lcidm = args->lcidm; + ch->srtm = args->srtm; +#ifndef OPENSSL_NO_QLOG + ch->use_qlog = args->use_qlog; + + if (ch->use_qlog && args->qlog_title != NULL) { + if ((ch->qlog_title = OPENSSL_strdup(args->qlog_title)) == NULL) { + OPENSSL_free(ch); + return NULL; + } + } +#endif if (!ch_init(ch)) { OPENSSL_free(ch); @@ -613,7 +496,7 @@ int ossl_quic_channel_set_peer_addr(QUIC_CHANNEL *ch, const BIO_ADDR *peer_addr) QUIC_REACTOR *ossl_quic_channel_get_reactor(QUIC_CHANNEL *ch) { - return &ch->rtor; + return ossl_quic_port_get0_reactor(ch->port); } QUIC_STREAM_MAP *ossl_quic_channel_get_qsm(QUIC_CHANNEL *ch) @@ -682,17 +565,27 @@ int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch) QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch) { - return ch->demux; + return ch->port->demux; +} + +QUIC_PORT *ossl_quic_channel_get0_port(QUIC_CHANNEL *ch) +{ + return ch->port; +} + +QUIC_ENGINE *ossl_quic_channel_get0_engine(QUIC_CHANNEL *ch) +{ + return ossl_quic_port_get0_engine(ch->port); } CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch) { - return ch->mutex; + return ossl_quic_port_get0_mutex(ch->port); } int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch) { - return ossl_quic_demux_has_pending(ch->demux) + return ossl_quic_demux_has_pending(ch->port->demux) || ossl_qrx_processed_read_pending(ch->qrx); } @@ -706,10 +599,7 @@ static OSSL_TIME get_time(void *arg) { QUIC_CHANNEL *ch = arg; - if (ch->now_cb == NULL) - return ossl_time_now(); - - return ch->now_cb(ch->now_cb_arg); + return ossl_quic_port_get_time(ch->port); } /* Used by QSM. */ @@ -747,7 +637,7 @@ static void ch_trigger_txku(QUIC_CHANNEL *ch) if (!ossl_quic_pn_valid(next_pn) || !ossl_qtx_trigger_key_update(ch->qtx)) { - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0, "key update"); return; } @@ -895,7 +785,7 @@ static void rxku_detected(QUIC_PN pn, void *arg) decision = DECISION_SOLICITED_TXKU; if (decision == DECISION_PROTOCOL_VIOLATION) { - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_KEY_UPDATE_ERROR, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_KEY_UPDATE_ERROR, 0, "RX key update again too soon"); return; } @@ -943,7 +833,7 @@ static void ch_rxku_tick(QUIC_CHANNEL *ch) ch->rxku_in_progress = 0; if (!ossl_qrx_key_update_timeout(ch->qrx, /*normal=*/1)) - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0, "RXKU cooldown internal error"); } @@ -1023,7 +913,7 @@ static int ch_on_crypto_recv_record(const unsigned char **buf, if (i != QUIC_ENC_LEVEL_0RTT && !crypto_ensure_empty(ch->crypto_recv[ossl_quic_enc_level_to_pn_space(i)])) { /* Protocol violation (RFC 9001 s. 4.1.3) */ - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION, OSSL_QUIC_FRAME_TYPE_CRYPTO, "crypto stream data in wrong EL"); return 0; @@ -1101,7 +991,7 @@ static int ch_on_handshake_yield_secret(uint32_t enc_level, int direction, for (i = QUIC_ENC_LEVEL_INITIAL; i < enc_level; ++i) if (!crypto_ensure_empty(ch->crypto_recv[ossl_quic_enc_level_to_pn_space(i)])) { /* Protocol violation (RFC 9001 s. 4.1.3) */ - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION, OSSL_QUIC_FRAME_TYPE_CRYPTO, "crypto stream data in wrong EL"); return 0; @@ -1134,7 +1024,7 @@ static int ch_on_handshake_complete(void *arg) * Was not a valid QUIC handshake if we did not get valid transport * params. */ - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_CRYPTO_MISSING_EXT, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_CRYPTO_MISSING_EXT, OSSL_QUIC_FRAME_TYPE_CRYPTO, "no transport parameters received"); return 0; @@ -1161,6 +1051,7 @@ static int ch_on_handshake_complete(void *arg) ossl_quic_tx_packetiser_schedule_handshake_done(ch->txp); } + ch_record_state_transition(ch, ch->state); return 1; } @@ -1177,7 +1068,7 @@ static int ch_on_handshake_alert(void *arg, unsigned char alert_code) && ch->handshake_complete && ossl_quic_tls_is_cert_request(ch->qtls)) ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, "Post-handshake TLS " "CertificateRequest received"); @@ -1192,12 +1083,12 @@ static int ch_on_handshake_alert(void *arg, unsigned char alert_code) && ch->handshake_complete && ossl_quic_tls_has_bad_max_early_data(ch->qtls)) ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, "Bad max_early_data received"); else ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_CRYPTO_ERR_BEGIN + OSSL_QUIC_ERR_CRYPTO_ERR_BEGIN + alert_code, 0, "handshake alert"); @@ -1254,6 +1145,16 @@ static void do_update(QUIC_STREAM *s, void *arg) ossl_quic_stream_map_update_state(&ch->qsm, s); } +static uint64_t min_u64_ignore_0(uint64_t a, uint64_t b) +{ + if (a == 0) + return b; + if (b == 0) + return a; + + return a < b ? a : b; +} + static int ch_on_transport_params(const unsigned char *params, size_t params_len, void *arg) @@ -1282,6 +1183,9 @@ static int ch_on_transport_params(const unsigned char *params, int got_disable_active_migration = 0; QUIC_CONN_ID cid; const char *reason = "bad transport parameter"; + ossl_unused uint64_t rx_max_idle_timeout = 0; + ossl_unused const void *stateless_reset_token_p = NULL; + QUIC_PREFERRED_ADDR pfa; if (ch->got_remote_transport_params) { reason = "multiple transport parameter extensions"; @@ -1289,7 +1193,7 @@ static int ch_on_transport_params(const unsigned char *params, } if (!PACKET_buf_init(&pkt, params, params_len)) { - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0, "internal error (packet buf init)"); return 0; } @@ -1540,11 +1444,15 @@ static int ch_on_transport_params(const unsigned char *params, goto malformed; } - if (v > 0 && v < ch->max_idle_timeout) - ch->max_idle_timeout = v; + ch->max_idle_timeout_remote_req = v; + + ch->max_idle_timeout = min_u64_ignore_0(ch->max_idle_timeout_local_req, + ch->max_idle_timeout_remote_req); + ch_update_idle(ch); got_max_idle_timeout = 1; + rx_max_idle_timeout = v; break; case QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE: @@ -1603,53 +1511,52 @@ static int ch_on_transport_params(const unsigned char *params, reason = TP_REASON_MALFORMED("STATELESS_RESET_TOKEN"); goto malformed; } - if (!chan_add_reset_token(ch, body, ch->cur_remote_seq_num)) { + if (!ossl_quic_srtm_add(ch->srtm, ch, ch->cur_remote_seq_num, + (const QUIC_STATELESS_RESET_TOKEN *)body)) { reason = TP_REASON_INTERNAL_ERROR("STATELESS_RESET_TOKEN"); goto malformed; } - got_stateless_reset_token = 1; + stateless_reset_token_p = body; + got_stateless_reset_token = 1; break; case QUIC_TPARAM_PREFERRED_ADDR: - { - /* TODO(QUIC FUTURE): Handle preferred address. */ - QUIC_PREFERRED_ADDR pfa; - if (got_preferred_addr) { - reason = TP_REASON_DUP("PREFERRED_ADDR"); - goto malformed; - } + /* TODO(QUIC FUTURE): Handle preferred address. */ + if (got_preferred_addr) { + reason = TP_REASON_DUP("PREFERRED_ADDR"); + goto malformed; + } - /* - * RFC 9000 s. 18.2: "A server that chooses a zero-length - * connection ID MUST NOT provide a preferred address. - * Similarly, a server MUST NOT include a zero-length connection - * ID in this transport parameter. A client MUST treat a - * violation of these requirements as a connection error of type - * TRANSPORT_PARAMETER_ERROR." - */ - if (ch->is_server) { - reason = TP_REASON_SERVER_ONLY("PREFERRED_ADDR"); - goto malformed; - } - - if (ch->cur_remote_dcid.id_len == 0) { - reason = "PREFERRED_ADDR provided for zero-length CID"; - goto malformed; - } - - if (!ossl_quic_wire_decode_transport_param_preferred_addr(&pkt, &pfa)) { - reason = TP_REASON_MALFORMED("PREFERRED_ADDR"); - goto malformed; - } - - if (pfa.cid.id_len == 0) { - reason = "zero-length CID in PREFERRED_ADDR"; - goto malformed; - } - - got_preferred_addr = 1; + /* + * RFC 9000 s. 18.2: "A server that chooses a zero-length + * connection ID MUST NOT provide a preferred address. + * Similarly, a server MUST NOT include a zero-length connection + * ID in this transport parameter. A client MUST treat a + * violation of these requirements as a connection error of type + * TRANSPORT_PARAMETER_ERROR." + */ + if (ch->is_server) { + reason = TP_REASON_SERVER_ONLY("PREFERRED_ADDR"); + goto malformed; + } + + if (ch->cur_remote_dcid.id_len == 0) { + reason = "PREFERRED_ADDR provided for zero-length CID"; + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_preferred_addr(&pkt, &pfa)) { + reason = TP_REASON_MALFORMED("PREFERRED_ADDR"); + goto malformed; } + + if (pfa.cid.id_len == 0) { + reason = "zero-length CID in PREFERRED_ADDR"; + goto malformed; + } + + got_preferred_addr = 1; break; case QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION: @@ -1707,6 +1614,65 @@ static int ch_on_transport_params(const unsigned char *params, ch->got_remote_transport_params = 1; +#ifndef OPENSSL_NO_QLOG + QLOG_EVENT_BEGIN(ch_get_qlog(ch), transport, parameters_set) + QLOG_STR("owner", "remote"); + + if (got_orig_dcid) + QLOG_CID("original_destination_connection_id", + &ch->init_dcid); + if (got_initial_scid) + QLOG_CID("original_source_connection_id", + &ch->init_dcid); + if (got_retry_scid) + QLOG_CID("retry_source_connection_id", + &ch->retry_scid); + if (got_initial_max_data) + QLOG_U64("initial_max_data", + ossl_quic_txfc_get_cwm(&ch->conn_txfc)); + if (got_initial_max_stream_data_bidi_local) + QLOG_U64("initial_max_stream_data_bidi_local", + ch->rx_init_max_stream_data_bidi_local); + if (got_initial_max_stream_data_bidi_remote) + QLOG_U64("initial_max_stream_data_bidi_remote", + ch->rx_init_max_stream_data_bidi_remote); + if (got_initial_max_stream_data_uni) + QLOG_U64("initial_max_stream_data_uni", + ch->rx_init_max_stream_data_uni); + if (got_initial_max_streams_bidi) + QLOG_U64("initial_max_streams_bidi", + ch->max_local_streams_bidi); + if (got_initial_max_streams_uni) + QLOG_U64("initial_max_streams_uni", + ch->max_local_streams_uni); + if (got_ack_delay_exp) + QLOG_U64("ack_delay_exponent", ch->rx_ack_delay_exp); + if (got_max_ack_delay) + QLOG_U64("max_ack_delay", ch->rx_max_ack_delay); + if (got_max_udp_payload_size) + QLOG_U64("max_udp_payload_size", ch->rx_max_udp_payload_size); + if (got_max_idle_timeout) + QLOG_U64("max_idle_timeout", rx_max_idle_timeout); + if (got_active_conn_id_limit) + QLOG_U64("active_connection_id_limit", ch->rx_active_conn_id_limit); + if (got_stateless_reset_token) + QLOG_BIN("stateless_reset_token", stateless_reset_token_p, + QUIC_STATELESS_RESET_TOKEN_LEN); + if (got_preferred_addr) { + QLOG_BEGIN("preferred_addr") + QLOG_U64("port_v4", pfa.ipv4_port); + QLOG_U64("port_v6", pfa.ipv6_port); + QLOG_BIN("ip_v4", pfa.ipv4, sizeof(pfa.ipv4)); + QLOG_BIN("ip_v6", pfa.ipv6, sizeof(pfa.ipv6)); + QLOG_BIN("stateless_reset_token", pfa.stateless_reset.token, + sizeof(pfa.stateless_reset.token)); + QLOG_CID("connection_id", &pfa.cid); + QLOG_END() + } + QLOG_BOOL("disable_active_migration", got_disable_active_migration); + QLOG_EVENT_END() +#endif + if (got_initial_max_data || got_initial_max_stream_data_bidi_remote || got_initial_max_streams_bidi || got_initial_max_streams_uni) /* @@ -1717,7 +1683,7 @@ static int ch_on_transport_params(const unsigned char *params, /* If we are a server, we now generate our own transport parameters. */ if (ch->is_server && !ch_generate_transport_params(ch)) { - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0, "internal error"); return 0; } @@ -1725,7 +1691,7 @@ static int ch_on_transport_params(const unsigned char *params, return 1; malformed: - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_TRANSPORT_PARAMETER_ERROR, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_TRANSPORT_PARAMETER_ERROR, 0, reason); return 0; } @@ -1743,7 +1709,7 @@ static int ch_generate_transport_params(QUIC_CHANNEL *ch) int wpkt_valid = 0; size_t buf_len = 0; - if (ch->local_transport_params != NULL) + if (ch->local_transport_params != NULL || ch->got_local_transport_params) goto err; if ((buf_mem = BUF_MEM_new()) == NULL) @@ -1774,7 +1740,7 @@ static int ch_generate_transport_params(QUIC_CHANNEL *ch) } if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_IDLE_TIMEOUT, - ch->max_idle_timeout)) + ch->max_idle_timeout_local_req)) goto err; if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE, @@ -1831,6 +1797,36 @@ static int ch_generate_transport_params(QUIC_CHANNEL *ch) buf_len)) goto err; +#ifndef OPENSSL_NO_QLOG + QLOG_EVENT_BEGIN(ch_get_qlog(ch), transport, parameters_set) + QLOG_STR("owner", "local"); + QLOG_BOOL("disable_active_migration", 1); + if (ch->is_server) { + QLOG_CID("original_destination_connection_id", &ch->init_dcid); + QLOG_CID("initial_source_connection_id", &ch->cur_local_cid); + } else { + QLOG_STR("initial_source_connection_id", ""); + } + QLOG_U64("max_idle_timeout", ch->max_idle_timeout); + QLOG_U64("max_udp_payload_size", QUIC_MIN_INITIAL_DGRAM_LEN); + QLOG_U64("active_connection_id_limit", QUIC_MIN_ACTIVE_CONN_ID_LIMIT); + QLOG_U64("max_ack_delay", ch->tx_max_ack_delay); + QLOG_U64("initial_max_data", ossl_quic_rxfc_get_cwm(&ch->conn_rxfc)); + QLOG_U64("initial_max_stream_data_bidi_local", + ch->tx_init_max_stream_data_bidi_local); + QLOG_U64("initial_max_stream_data_bidi_remote", + ch->tx_init_max_stream_data_bidi_remote); + QLOG_U64("initial_max_stream_data_uni", + ch->tx_init_max_stream_data_uni); + QLOG_U64("initial_max_streams_bidi", + ossl_quic_rxfc_get_cwm(&ch->max_streams_bidi_rxfc)); + QLOG_U64("initial_max_streams_uni", + ossl_quic_rxfc_get_cwm(&ch->max_streams_uni_rxfc)); + QLOG_EVENT_END() +#endif + + ch->got_local_transport_params = 1; + ok = 1; err: if (wpkt_valid) @@ -1849,20 +1845,20 @@ static int ch_generate_transport_params(QUIC_CHANNEL *ch) * at least everything network I/O related. Best effort - not allowed to fail * "loudly". */ -static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) +void ossl_quic_channel_subtick(QUIC_CHANNEL *ch, QUIC_TICK_RESULT *res, + uint32_t flags) { OSSL_TIME now, deadline; - QUIC_CHANNEL *ch = arg; int channel_only = (flags & QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY) != 0; /* * When we tick the QUIC connection, we do everything we need to do - * periodically. In order, we: + * periodically. Network I/O handling will already have been performed + * as necessary by the QUIC port. Thus, in order, we: * - * - handle any incoming data from the network; - * - handle any timer events which are due to fire (ACKM, etc.) - * - write any data to the network due to be sent, to the extent - * possible; + * - handle any packets the DEMUX has queued up for us; + * - handle any timer events which are due to fire (ACKM, etc.); + * - generate any packets which need to be sent; * - determine the time at which we should next be ticked. */ @@ -1890,13 +1886,10 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) } } - if (!ch->inhibit_tick) { + if (!ch->port->engine->inhibit_tick) { /* Handle RXKU timeouts. */ ch_rxku_tick(ch); - /* Handle any incoming data from network. */ - ch_rx_pre(ch); - do { /* Process queued incoming packets. */ ch->did_tls_tick = 0; @@ -1933,7 +1926,7 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) * Idle timeout differs from normal protocol violation because we do * not send a CONN_CLOSE frame; go straight to TERMINATED. */ - if (!ch->inhibit_tick) + if (!ch->port->engine->inhibit_tick) ch_on_idle_timeout(ch); res->net_read_desired = 0; @@ -1942,7 +1935,7 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) return; } - if (!ch->inhibit_tick) { + if (!ch->port->engine->inhibit_tick) { deadline = ossl_ackm_get_loss_detection_deadline(ch->ackm); if (!ossl_time_is_zero(deadline) && ossl_time_compare(now, deadline) >= 0) @@ -1964,7 +1957,7 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) ch_update_ping_deadline(ch); } - /* Write any data to the network due to be sent. */ + /* Queue any data to be sent for transmission. */ ch_tx(ch); /* Do stream GC. */ @@ -1975,14 +1968,13 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) res->tick_deadline = ch_determine_next_tick_deadline(ch); /* - * Always process network input unless we are now terminated. - * Although we had not terminated at the beginning of this tick, network - * errors in ch_rx_pre() or ch_tx() may have caused us to transition to the - * Terminated state. + * Always process network input unless we are now terminated. Although we + * had not terminated at the beginning of this tick, network errors in + * ch_tx() may have caused us to transition to the Terminated state. */ res->net_read_desired = !ossl_quic_channel_is_terminated(ch); - /* We want to write to the network if we have any in our queue. */ + /* We want to write to the network if we have any data in our TX queue. */ res->net_write_desired = (!ossl_quic_channel_is_terminated(ch) && ossl_qtx_get_queue_len_datagrams(ch->qtx) > 0); @@ -2010,32 +2002,6 @@ static int ch_tick_tls(QUIC_CHANNEL *ch, int channel_only) return 1; } -/* Process incoming datagrams, if any. */ -static void ch_rx_pre(QUIC_CHANNEL *ch) -{ - int ret; - - if (!ch->is_server && !ch->have_sent_any_pkt) - return; - - /* - * Get DEMUX to BIO_recvmmsg from the network and queue incoming datagrams - * to the appropriate QRX instance. - */ - ret = ossl_quic_demux_pump(ch->demux); - if (ret == QUIC_DEMUX_PUMP_RES_STATELESS_RESET) - ch_stateless_reset(ch); - else if (ret == QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL) - /* - * We don't care about transient failure, but permanent failure means we - * should tear down the connection as though a protocol violation - * occurred. Skip straight to the Terminating state as there is no point - * trying to send CONNECTION_CLOSE frames if the network BIO is not - * operating correctly. - */ - ch_raise_net_error(ch); -} - /* Check incoming forged packet limit and terminate connection if needed. */ static void ch_rx_check_forged_pkt_limit(QUIC_CHANNEL *ch) { @@ -2064,7 +2030,7 @@ static void ch_rx_check_forged_pkt_limit(QUIC_CHANNEL *ch) if (ossl_qrx_get_cur_forged_pkt_count(ch->qrx) < limit) return; - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_AEAD_LIMIT_REACHED, 0, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_AEAD_LIMIT_REACHED, 0, "forgery limit"); } @@ -2153,6 +2119,7 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only) { uint32_t enc_level; int old_have_processed_any_pkt = ch->have_processed_any_pkt; + OSSL_QTX_IOVEC iovec; assert(ch->qrx_pkt != NULL); @@ -2234,11 +2201,17 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only) */ if (ossl_quic_pkt_type_is_encrypted(ch->qrx_pkt->hdr->type) && ch->qrx_pkt->hdr->reserved != 0) { - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, "packet header reserved bits"); return; } + iovec.buf = ch->qrx_pkt->hdr->data; + iovec.buf_len = ch->qrx_pkt->hdr->len; + ossl_qlog_event_transport_packet_received(ch_get_qlog(ch), ch->qrx_pkt->hdr, + ch->qrx_pkt->pn, &iovec, 1, + ch->qrx_pkt->datagram_id); + /* Handle incoming packet. */ switch (ch->qrx_pkt->hdr->type) { case QUIC_PKT_TYPE_RETRY: @@ -2270,8 +2243,8 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only) * than allow the QRX to emit a potentially malformed packet to the * upper layers. However, special casing this will do for now. */ - if (!ossl_quic_validate_retry_integrity_tag(ch->libctx, - ch->propq, + if (!ossl_quic_validate_retry_integrity_tag(ch->port->engine->libctx, + ch->port->engine->propq, ch->qrx_pkt->hdr, &ch->init_dcid)) /* Malformed retry packet, ignore. */ @@ -2280,7 +2253,7 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only) if (!ch_retry(ch, ch->qrx_pkt->hdr->data, ch->qrx_pkt->hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN, &ch->qrx_pkt->hdr->src_conn_id)) - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0, "handling retry packet"); break; @@ -2318,7 +2291,7 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only) * were used for packets with lower packet numbers MUST treat this * as a connection error of type KEY_UPDATE_ERROR. */ - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_KEY_UPDATE_ERROR, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_KEY_UPDATE_ERROR, 0, "new packet with old keys"); break; } @@ -2343,7 +2316,7 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only) * packets that lack authentication. * I.e. should we drop this packet instead of closing the connection? */ - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, "client received initial token"); break; } @@ -2402,7 +2375,7 @@ static void ch_raise_version_neg_failure(QUIC_CHANNEL *ch) { QUIC_TERMINATE_CAUSE tcause = {0}; - tcause.error_code = QUIC_ERR_CONNECTION_REFUSED; + tcause.error_code = OSSL_QUIC_ERR_CONNECTION_REFUSED; tcause.reason = "version negotiation failure"; tcause.reason_len = strlen(tcause.reason); @@ -2413,87 +2386,6 @@ static void ch_raise_version_neg_failure(QUIC_CHANNEL *ch) ch_start_terminating(ch, &tcause, 1); } -/* - * This is called by the demux when we get a packet not destined for any known - * DCID. - */ -static void ch_default_packet_handler(QUIC_URXE *e, void *arg) -{ - QUIC_CHANNEL *ch = arg; - PACKET pkt; - QUIC_PKT_HDR hdr; - - if (!ossl_assert(ch->is_server)) - goto undesirable; - - /* - * We only support one connection to our server currently, so if we already - * started one, ignore any new connection attempts. - */ - if (ch->state != QUIC_CHANNEL_STATE_IDLE) - goto undesirable; - - /* - * We have got a packet for an unknown DCID. This might be an attempt to - * open a new connection. - */ - if (e->data_len < QUIC_MIN_INITIAL_DGRAM_LEN) - goto undesirable; - - if (!PACKET_buf_init(&pkt, ossl_quic_urxe_data(e), e->data_len)) - goto err; - - /* - * We set short_conn_id_len to SIZE_MAX here which will cause the decode - * operation to fail if we get a 1-RTT packet. This is fine since we only - * care about Initial packets. - */ - if (!ossl_quic_wire_decode_pkt_hdr(&pkt, SIZE_MAX, 1, 0, &hdr, NULL)) - goto undesirable; - - switch (hdr.version) { - case QUIC_VERSION_1: - break; - - case QUIC_VERSION_NONE: - default: - /* Unknown version or proactive version negotiation request, bail. */ - /* TODO(QUIC SERVER): Handle version negotiation on server side */ - goto undesirable; - } - - /* - * We only care about Initial packets which might be trying to establish a - * connection. - */ - if (hdr.type != QUIC_PKT_TYPE_INITIAL) - goto undesirable; - - /* - * Assume this is a valid attempt to initiate a connection. - * - * We do not register the DCID in the initial packet we received and that - * DCID is not actually used again, thus after provisioning the correct - * Initial keys derived from it (which is done in the call below) we pass - * the received packet directly to the QRX so that it can process it as a - * one-time thing, instead of going through the usual DEMUX DCID-based - * routing. - */ - if (!ch_server_on_new_conn(ch, &e->peer, - &hdr.src_conn_id, - &hdr.dst_conn_id)) - goto err; - - ossl_qrx_inject_urxe(ch->qrx, e); - return; - -err: - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, - "internal error"); -undesirable: - ossl_quic_demux_release_urxe(ch->demux, e); -} - /* Try to generate packets and if possible, flush them to the network. */ static int ch_tx(QUIC_CHANNEL *ch) { @@ -2544,6 +2436,7 @@ static int ch_tx(QUIC_CHANNEL *ch) res = ossl_quic_tx_packetiser_generate(ch->txp, &status); if (status.sent_pkt > 0) { ch->have_sent_any_pkt = 1; /* Packet(s) were sent */ + ch->port->have_sent_any_pkt = 1; /* * RFC 9000 s. 10.1. 'An endpoint also restarts its idle timer when @@ -2582,7 +2475,7 @@ static int ch_tx(QUIC_CHANNEL *ch) * to schedule a CONNECTION_CLOSE frame will not actually cause a * packet to be transmitted for this reason. */ - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0, "internal error (txp generate)"); break; @@ -2599,7 +2492,7 @@ static int ch_tx(QUIC_CHANNEL *ch) case QTX_FLUSH_NET_RES_PERMANENT_FAIL: default: /* Permanent underlying network BIO, start terminating. */ - ch_raise_net_error(ch); + ossl_quic_port_raise_net_error(ch->port, ch); break; } @@ -2658,101 +2551,27 @@ static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch) } /* - * QUIC Channel: Network BIO Configuration - * ======================================= + * QUIC Channel: Lifecycle Events + * ============================== */ -/* Determines whether we can support a given poll descriptor. */ -static int validate_poll_descriptor(const BIO_POLL_DESCRIPTOR *d) -{ - if (d->type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD && d->value.fd < 0) { - ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); - return 0; - } - - return 1; -} - -BIO *ossl_quic_channel_get_net_rbio(QUIC_CHANNEL *ch) -{ - return ch->net_rbio; -} - -BIO *ossl_quic_channel_get_net_wbio(QUIC_CHANNEL *ch) -{ - return ch->net_wbio; -} - -static int ch_update_poll_desc(QUIC_CHANNEL *ch, BIO *net_bio, int for_write) -{ - BIO_POLL_DESCRIPTOR d = {0}; - - if (net_bio == NULL - || (!for_write && !BIO_get_rpoll_descriptor(net_bio, &d)) - || (for_write && !BIO_get_wpoll_descriptor(net_bio, &d))) - /* Non-pollable BIO */ - d.type = BIO_POLL_DESCRIPTOR_TYPE_NONE; - - if (!validate_poll_descriptor(&d)) - return 0; - - if (for_write) - ossl_quic_reactor_set_poll_w(&ch->rtor, &d); - else - ossl_quic_reactor_set_poll_r(&ch->rtor, &d); - - return 1; -} - -int ossl_quic_channel_update_poll_descriptors(QUIC_CHANNEL *ch) -{ - int ok = 1; - - if (!ch_update_poll_desc(ch, ch->net_rbio, /*for_write=*/0)) - ok = 0; - - if (!ch_update_poll_desc(ch, ch->net_wbio, /*for_write=*/1)) - ok = 0; - - return ok; -} - /* - * QUIC_CHANNEL does not ref any BIO it is provided with, nor is any ref - * transferred to it. The caller (i.e., QUIC_CONNECTION) is responsible for - * ensuring the BIO lasts until the channel is freed or the BIO is switched out - * for another BIO by a subsequent successful call to this function. + * Record a state transition. This is not necessarily a change to ch->state but + * also includes the handshake becoming complete or confirmed, etc. */ -int ossl_quic_channel_set_net_rbio(QUIC_CHANNEL *ch, BIO *net_rbio) -{ - if (ch->net_rbio == net_rbio) - return 1; - - if (!ch_update_poll_desc(ch, net_rbio, /*for_write=*/0)) - return 0; - - ossl_quic_demux_set_bio(ch->demux, net_rbio); - ch->net_rbio = net_rbio; - return 1; -} - -int ossl_quic_channel_set_net_wbio(QUIC_CHANNEL *ch, BIO *net_wbio) +static void ch_record_state_transition(QUIC_CHANNEL *ch, uint32_t new_state) { - if (ch->net_wbio == net_wbio) - return 1; + uint32_t old_state = ch->state; - if (!ch_update_poll_desc(ch, net_wbio, /*for_write=*/1)) - return 0; + ch->state = new_state; - ossl_qtx_set_bio(ch->qtx, net_wbio); - ch->net_wbio = net_wbio; - return 1; + ossl_qlog_event_connectivity_connection_state_updated(ch_get_qlog(ch), + old_state, + new_state, + ch->handshake_complete, + ch->handshake_confirmed); } -/* - * QUIC Channel: Lifecycle Events - * ============================== - */ int ossl_quic_channel_start(QUIC_CHANNEL *ch) { if (ch->is_server) @@ -2771,22 +2590,34 @@ int ossl_quic_channel_start(QUIC_CHANNEL *ch) return 0; /* Plug in secrets for the Initial EL. */ - if (!ossl_quic_provide_initial_secret(ch->libctx, - ch->propq, + if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx, + ch->port->engine->propq, &ch->init_dcid, ch->is_server, ch->qrx, ch->qtx)) return 0; + /* + * Determine the QUIC Transport Parameters and serialize the transport + * parameters block. (For servers, we do this later as we must defer + * generation until we have received the client's transport parameters.) + */ + if (!ch->is_server && !ch->got_local_transport_params + && !ch_generate_transport_params(ch)) + return 0; + /* Change state. */ - ch->state = QUIC_CHANNEL_STATE_ACTIVE; + ch_record_state_transition(ch, QUIC_CHANNEL_STATE_ACTIVE); ch->doing_proactive_ver_neg = 0; /* not currently supported */ + ossl_qlog_event_connectivity_connection_started(ch_get_qlog(ch), + &ch->init_dcid); + /* Handshake layer: start (e.g. send CH). */ if (!ch_tick_tls(ch, /*channel_only=*/0)) return 0; - ossl_quic_reactor_tick(&ch->rtor, 0); /* best effort */ + ossl_quic_reactor_tick(ossl_quic_port_get0_reactor(ch->port), 0); /* best effort */ return 1; } @@ -2844,7 +2675,7 @@ static int ch_retry(QUIC_CHANNEL *ch, * This may fail if the token we receive is too big for us to ever be * able to transmit in an outgoing Initial packet. */ - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INVALID_TOKEN, 0, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INVALID_TOKEN, 0, "received oversize token"); OPENSSL_free(buf); return 0; @@ -2871,8 +2702,8 @@ static int ch_retry(QUIC_CHANNEL *ch, * Plug in new secrets for the Initial EL. This is the only time we change * the secrets for an EL after we already provisioned it. */ - if (!ossl_quic_provide_initial_secret(ch->libctx, - ch->propq, + if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx, + ch->port->engine->propq, &ch->retry_scid, /*is_server=*/0, ch->qrx, ch->qtx)) @@ -2930,7 +2761,7 @@ int ossl_quic_channel_on_handshake_confirmed(QUIC_CHANNEL *ch) * Does not make sense for handshake to be confirmed before it is * completed. */ - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE, "handshake cannot be confirmed " "before it is completed"); @@ -2939,6 +2770,7 @@ int ossl_quic_channel_on_handshake_confirmed(QUIC_CHANNEL *ch) ch_discard_el(ch, QUIC_ENC_LEVEL_HANDSHAKE); ch->handshake_confirmed = 1; + ch_record_state_transition(ch, ch->state); ossl_ackm_on_handshake_confirmed(ch->ackm); return 1; } @@ -3037,9 +2869,12 @@ static void ch_start_terminating(QUIC_CHANNEL *ch, case QUIC_CHANNEL_STATE_ACTIVE: copy_tcause(&ch->terminate_cause, tcause); + ossl_qlog_event_connectivity_connection_closed(ch_get_qlog(ch), tcause); + if (!force_immediate) { - ch->state = tcause->remote ? QUIC_CHANNEL_STATE_TERMINATING_DRAINING - : QUIC_CHANNEL_STATE_TERMINATING_CLOSING; + ch_record_state_transition(ch, tcause->remote + ? QUIC_CHANNEL_STATE_TERMINATING_DRAINING + : QUIC_CHANNEL_STATE_TERMINATING_CLOSING); /* * RFC 9000 s. 10.2 Immediate Close * These states SHOULD persist for at least three times @@ -3084,7 +2919,7 @@ static void ch_start_terminating(QUIC_CHANNEL *ch, * closing state if it receives a CONNECTION_CLOSE frame, * which indicates that the peer is also closing or draining. */ - ch->state = QUIC_CHANNEL_STATE_TERMINATING_DRAINING; + ch_record_state_transition(ch, QUIC_CHANNEL_STATE_TERMINATING_DRAINING); break; @@ -3133,7 +2968,7 @@ static int ch_enqueue_retire_conn_id(QUIC_CHANNEL *ch, uint64_t seq_num) WPACKET wpkt; size_t l; - chan_remove_reset_token(ch, seq_num); + ossl_quic_srtm_remove(ch->srtm, ch, seq_num); if ((buf_mem = BUF_MEM_new()) == NULL) goto err; @@ -3162,7 +2997,7 @@ static int ch_enqueue_retire_conn_id(QUIC_CHANNEL *ch, uint64_t seq_num) err: ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, "internal error enqueueing retire conn id"); BUF_MEM_free(buf_mem); @@ -3182,7 +3017,7 @@ void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch, if (ch->cur_remote_dcid.id_len == 0) { /* Changing from 0 length connection id is disallowed */ ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, "zero length connection id in use"); @@ -3206,7 +3041,7 @@ void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch, */ if (new_remote_seq_num - new_retire_prior_to > 1) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_CONNECTION_ID_LIMIT_ERROR, + OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, "active_connection_id limit violated"); return; @@ -3229,7 +3064,7 @@ void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch, */ if (new_retire_prior_to - ch->cur_retire_prior_to > 10) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_CONNECTION_ID_LIMIT_ERROR, + OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, "retiring connection id limit violated"); @@ -3238,10 +3073,10 @@ void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch, if (new_remote_seq_num > ch->cur_remote_seq_num) { /* Add new stateless reset token */ - if (!chan_add_reset_token(ch, f->stateless_reset.token, - new_remote_seq_num)) { + if (!ossl_quic_srtm_add(ch->srtm, ch, new_remote_seq_num, + &f->stateless_reset)) { ossl_quic_channel_raise_protocol_error( - ch, QUIC_ERR_CONNECTION_ID_LIMIT_ERROR, + ch, OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, "unable to store stateless reset token"); @@ -3290,25 +3125,32 @@ static void ch_save_err_state(QUIC_CHANNEL *ch) OSSL_ERR_STATE_save(ch->err_state); } -static void ch_stateless_reset(QUIC_CHANNEL *ch) +void ossl_quic_channel_inject(QUIC_CHANNEL *ch, QUIC_URXE *e) +{ + ossl_qrx_inject_urxe(ch->qrx, e); +} + +void ossl_quic_channel_on_stateless_reset(QUIC_CHANNEL *ch) { QUIC_TERMINATE_CAUSE tcause = {0}; - tcause.error_code = QUIC_ERR_NO_ERROR; - ch_start_terminating(ch, &tcause, 1); + tcause.error_code = OSSL_QUIC_ERR_NO_ERROR; + tcause.remote = 1; + ch_start_terminating(ch, &tcause, 0); } -static void ch_raise_net_error(QUIC_CHANNEL *ch) +void ossl_quic_channel_raise_net_error(QUIC_CHANNEL *ch) { QUIC_TERMINATE_CAUSE tcause = {0}; - ch->net_error = 1; + if (ch->net_error) + return; - ERR_raise_data(ERR_LIB_SSL, SSL_R_QUIC_NETWORK_ERROR, - "connection terminated due to network error"); - ch_save_err_state(ch); + ch->net_error = 1; - tcause.error_code = QUIC_ERR_INTERNAL_ERROR; + tcause.error_code = OSSL_QUIC_ERR_INTERNAL_ERROR; + tcause.reason = "network BIO I/O error"; + tcause.reason_len = strlen(tcause.reason); /* * Skip Terminating state and go directly to Terminated, no point trying to @@ -3327,7 +3169,10 @@ void ossl_quic_channel_restore_err_state(QUIC_CHANNEL *ch) if (ch == NULL) return; - OSSL_ERR_STATE_restore(ch->err_state); + if (!ossl_quic_port_is_running(ch->port)) + ossl_quic_port_restore_err_state(ch->port); + else + OSSL_ERR_STATE_restore(ch->err_state); } void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch, @@ -3340,7 +3185,7 @@ void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch, const char *src_func) { QUIC_TERMINATE_CAUSE tcause = {0}; - int err_reason = error_code == QUIC_ERR_INTERNAL_ERROR + int err_reason = error_code == OSSL_QUIC_ERR_INTERNAL_ERROR ? ERR_R_INTERNAL_ERROR : SSL_R_QUIC_PROTOCOL_ERROR; const char *err_str = ossl_quic_err_to_string(error_code); const char *err_str_pfx = " (", *err_str_sfx = ")"; @@ -3408,7 +3253,7 @@ void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch, */ static void ch_on_terminating_timeout(QUIC_CHANNEL *ch) { - ch->state = QUIC_CHANNEL_STATE_TERMINATED; + ch_record_state_transition(ch, QUIC_CHANNEL_STATE_TERMINATED); } /* @@ -3480,23 +3325,22 @@ static void ch_on_idle_timeout(QUIC_CHANNEL *ch) * TERMINATED anyway. */ ch->terminate_cause.app = 0; - ch->terminate_cause.error_code = UINT64_MAX; + ch->terminate_cause.error_code = OSSL_QUIC_LOCAL_ERR_IDLE_TIMEOUT; ch->terminate_cause.frame_type = 0; - ch->state = QUIC_CHANNEL_STATE_TERMINATED; + ch_record_state_transition(ch, QUIC_CHANNEL_STATE_TERMINATED); } /* Called when we, as a server, get a new incoming connection. */ -static int ch_server_on_new_conn(QUIC_CHANNEL *ch, const BIO_ADDR *peer, - const QUIC_CONN_ID *peer_scid, - const QUIC_CONN_ID *peer_dcid) +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) { if (!ossl_assert(ch->state == QUIC_CHANNEL_STATE_IDLE && ch->is_server)) return 0; - /* Generate a SCID we will use for the connection. */ - if (!gen_rand_conn_id(ch->libctx, INIT_DCID_LEN, - &ch->cur_local_cid)) + /* Generate an Initial LCID we will use for the connection. */ + if (!ossl_quic_lcidm_generate_initial(ch->lcidm, ch, &ch->cur_local_cid)) return 0; /* Note our newly learnt peer address and CIDs. */ @@ -3515,20 +3359,24 @@ static int ch_server_on_new_conn(QUIC_CHANNEL *ch, const BIO_ADDR *peer, if (!ossl_quic_tx_packetiser_set_cur_scid(ch->txp, &ch->cur_local_cid)) return 0; + /* Setup QLOG, which did not happen earlier due to lacking an Initial ODCID. */ + ossl_qtx_set_qlog_cb(ch->qtx, ch_get_qlog_cb, ch); + ossl_quic_tx_packetiser_set_qlog_cb(ch->txp, ch_get_qlog_cb, ch); + /* Plug in secrets for the Initial EL. */ - if (!ossl_quic_provide_initial_secret(ch->libctx, - ch->propq, + if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx, + ch->port->engine->propq, &ch->init_dcid, /*is_server=*/1, ch->qrx, ch->qtx)) return 0; - /* Register our local CID in the DEMUX. */ - if (!ossl_qrx_add_dst_conn_id(ch->qrx, &ch->cur_local_cid)) + /* Register the peer ODCID in the LCIDM. */ + if (!ossl_quic_lcidm_enrol_odcid(ch->lcidm, ch, &ch->init_dcid)) return 0; /* Change state. */ - ch->state = QUIC_CHANNEL_STATE_ACTIVE; + ch_record_state_transition(ch, QUIC_CHANNEL_STATE_ACTIVE); ch->doing_proactive_ver_neg = 0; /* not currently supported */ return 1; } @@ -3611,21 +3459,54 @@ static uint64_t *ch_get_local_stream_next_ordinal_ptr(QUIC_CHANNEL *ch, : &ch->next_local_stream_ordinal_bidi; } +static const uint64_t *ch_get_local_stream_max_ptr(const QUIC_CHANNEL *ch, + int is_uni) +{ + return is_uni ? &ch->max_local_streams_uni + : &ch->max_local_streams_bidi; +} + +static const QUIC_RXFC *ch_get_remote_stream_count_rxfc(const QUIC_CHANNEL *ch, + int is_uni) +{ + return is_uni ? &ch->max_streams_uni_rxfc + : &ch->max_streams_bidi_rxfc; +} + int ossl_quic_channel_is_new_local_stream_admissible(QUIC_CHANNEL *ch, int is_uni) { - uint64_t *p_next_ordinal = ch_get_local_stream_next_ordinal_ptr(ch, is_uni); + const uint64_t *p_next_ordinal = ch_get_local_stream_next_ordinal_ptr(ch, is_uni); return ossl_quic_stream_map_is_local_allowed_by_stream_limit(&ch->qsm, *p_next_ordinal, is_uni); } +uint64_t ossl_quic_channel_get_local_stream_count_avail(const QUIC_CHANNEL *ch, + int is_uni) +{ + const uint64_t *p_next_ordinal, *p_max; + + p_next_ordinal = ch_get_local_stream_next_ordinal_ptr((QUIC_CHANNEL *)ch, + is_uni); + p_max = ch_get_local_stream_max_ptr(ch, is_uni); + + return *p_max - *p_next_ordinal; +} + +uint64_t ossl_quic_channel_get_remote_stream_count_avail(const QUIC_CHANNEL *ch, + int is_uni) +{ + return ossl_quic_rxfc_get_credit(ch_get_remote_stream_count_rxfc(ch, is_uni)); +} + QUIC_STREAM *ossl_quic_channel_new_stream_local(QUIC_CHANNEL *ch, int is_uni) { QUIC_STREAM *qs; int type; - uint64_t stream_id, *p_next_ordinal; + uint64_t stream_id; + uint64_t *p_next_ordinal; type = ch->is_server ? QUIC_STREAM_INITIATOR_SERVER : QUIC_STREAM_INITIATOR_CLIENT; @@ -3718,15 +3599,16 @@ void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs) int ossl_quic_channel_replace_local_cid(QUIC_CHANNEL *ch, const QUIC_CONN_ID *conn_id) { - /* Remove the current local CID from the DEMUX. */ - if (!ossl_qrx_remove_dst_conn_id(ch->qrx, &ch->cur_local_cid)) + /* Remove the current LCID from the LCIDM. */ + if (!ossl_quic_lcidm_debug_remove(ch->lcidm, &ch->cur_local_cid)) return 0; ch->cur_local_cid = *conn_id; /* Set in the TXP, used only for long header packets. */ if (!ossl_quic_tx_packetiser_set_cur_scid(ch->txp, &ch->cur_local_cid)) return 0; - /* Register our new local CID in the DEMUX. */ - if (!ossl_qrx_add_dst_conn_id(ch->qrx, &ch->cur_local_cid)) + /* Add the new LCID to the LCIDM. */ + if (!ossl_quic_lcidm_debug_add(ch->lcidm, ch, &ch->cur_local_cid, + 100)) return 0; return 1; } @@ -3787,11 +3669,6 @@ int ossl_quic_channel_ping(QUIC_CHANNEL *ch) return 1; } -void ossl_quic_channel_set_inhibit_tick(QUIC_CHANNEL *ch, int inhibit) -{ - ch->inhibit_tick = (inhibit != 0); -} - uint16_t ossl_quic_channel_get_diag_num_rx_ack(QUIC_CHANNEL *ch) { return ch->diag_num_rx_ack; @@ -3801,3 +3678,27 @@ void ossl_quic_channel_get_diag_local_cid(QUIC_CHANNEL *ch, QUIC_CONN_ID *cid) { *cid = ch->cur_local_cid; } + +int ossl_quic_channel_have_generated_transport_params(const QUIC_CHANNEL *ch) +{ + return ch->got_local_transport_params; +} + +void ossl_quic_channel_set_max_idle_timeout_request(QUIC_CHANNEL *ch, uint64_t ms) +{ + ch->max_idle_timeout_local_req = ms; +} +uint64_t ossl_quic_channel_get_max_idle_timeout_request(const QUIC_CHANNEL *ch) +{ + return ch->max_idle_timeout_local_req; +} + +uint64_t ossl_quic_channel_get_max_idle_timeout_peer_request(const QUIC_CHANNEL *ch) +{ + return ch->max_idle_timeout_remote_req; +} + +uint64_t ossl_quic_channel_get_max_idle_timeout_actual(const QUIC_CHANNEL *ch) +{ + return ch->max_idle_timeout; +} diff --git a/libs/openssl-3/ssl/quic/quic_channel_local.h b/libs/openssl-3/ssl/quic/quic_channel_local.h index f0ac74242..16d96ef7d 100644 --- a/libs/openssl-3/ssl/quic/quic_channel_local.h +++ b/libs/openssl-3/ssl/quic/quic_channel_local.h @@ -7,17 +7,9 @@ # include # include "internal/list.h" - - -typedef struct quic_srt_elem_st QUIC_SRT_ELEM; - -struct quic_srt_elem_st { - OSSL_LIST_MEMBER(stateless_reset_tokens, QUIC_SRT_ELEM); - QUIC_STATELESS_RESET_TOKEN token; - uint64_t seq_num; -}; - -DEFINE_LIST_OF(stateless_reset_tokens, QUIC_SRT_ELEM); +# include "internal/quic_predef.h" +# include "internal/quic_fc.h" +# include "internal/quic_stream_map.h" /* * QUIC Channel Structure @@ -36,22 +28,13 @@ DEFINE_LIST_OF(stateless_reset_tokens, QUIC_SRT_ELEM); * Other components should not include this header. */ struct quic_channel_st { - OSSL_LIB_CTX *libctx; - const char *propq; + QUIC_PORT *port; /* - * Master synchronisation mutex used for thread assisted mode - * synchronisation. We don't own this; the instantiator of the channel - * passes it to us and is responsible for freeing it after channel - * destruction. + * QUIC_PORT keeps the channels which belong to it on a list for bookkeeping + * purposes. */ - CRYPTO_MUTEX *mutex; - - /* - * Callback used to get the current time. - */ - OSSL_TIME (*now_cb)(void *arg); - void *now_cb_arg; + OSSL_LIST_MEMBER(ch, struct quic_channel_st); /* * The associated TLS 1.3 connection data. Used to provide the handshake @@ -61,21 +44,23 @@ struct quic_channel_st { QUIC_TLS *qtls; SSL *tls; + /* Port LCIDM we use to register LCIDs. */ + QUIC_LCIDM *lcidm; + /* SRTM we register SRTs with. */ + QUIC_SRTM *srtm; + + /* Optional QLOG instance (or NULL). */ + QLOG *qlog; + /* * The transport parameter block we will send or have sent. * Freed after sending or when connection is freed. */ unsigned char *local_transport_params; - /* Asynchronous I/O reactor. */ - QUIC_REACTOR rtor; - /* Our current L4 peer address, if any. */ BIO_ADDR cur_peer_addr; - /* Network-side read and write BIOs. */ - BIO *net_rbio, *net_wbio; - /* * Subcomponents of the connection. All of these components are instantiated * and owned by us. @@ -96,14 +81,7 @@ struct quic_channel_st { const OSSL_CC_METHOD *cc_method; OSSL_ACKM *ackm; - /* - * RX demuxer. We register incoming DCIDs with this. Since we currently only - * support client operation and use one L4 port per connection, we own the - * demuxer and register a single zero-length DCID with it. - */ - QUIC_DEMUX *demux; - - /* Record layers in the TX and RX directions, plus the RX demuxer. */ + /* Record layers in the TX and RX directions. */ OSSL_QTX *qtx; OSSL_QRX *qrx; @@ -141,30 +119,16 @@ struct quic_channel_st { */ QUIC_CONN_ID retry_scid; + /* Server only: The DCID we currently expect the peer to use to talk to us. */ + QUIC_CONN_ID cur_local_cid; + /* * The DCID we currently use to talk to the peer and its sequence num. - * - * TODO(QUIC FUTURE) consider removing the second two, both are contained in - * srt_list_seq (defined below). - * - * cur_remote_seq_num is same as the sequence number in the last element. - * cur_retire_prior_to corresponds to the sequence number in first element. - * - * Leaving them here avoids null checking etc */ QUIC_CONN_ID cur_remote_dcid; uint64_t cur_remote_seq_num; uint64_t cur_retire_prior_to; - /* Server only: The DCID we currently expect the peer to use to talk to us. */ - QUIC_CONN_ID cur_local_cid; - - /* Hash of stateless reset tokens keyed on the token */ - LHASH_OF(QUIC_SRT_ELEM) *srt_hash_tok; - - /* List of the stateless reset tokens ordered by sequence number */ - OSSL_LIST(stateless_reset_tokens) srt_list_seq; - /* Transport parameter values we send to our peer. */ uint64_t tx_init_max_stream_data_bidi_local; uint64_t tx_init_max_stream_data_bidi_remote; @@ -178,6 +142,9 @@ struct quic_channel_st { uint64_t rx_max_ack_delay; /* ms */ unsigned char rx_ack_delay_exp; + /* Diagnostic counters for testing purposes only. May roll over. */ + uint16_t diag_num_rx_ack; /* Number of ACK frames received */ + /* * Temporary staging area to store information about the incoming packet we * are currently processing. @@ -191,6 +158,10 @@ struct quic_channel_st { uint64_t max_local_streams_bidi; uint64_t max_local_streams_uni; + /* The idle timeout values we and our peer requested. */ + uint64_t max_idle_timeout_local_req; + uint64_t max_idle_timeout_remote_req; + /* The negotiated maximum idle timeout in milliseconds. */ uint64_t max_idle_timeout; @@ -233,9 +204,6 @@ struct quic_channel_st { */ uint64_t txku_threshold_override; - /* Diagnostic counters for testing purposes only. May roll over. */ - uint16_t diag_num_rx_ack; /* Number of ACK frames received */ - /* Valid if we are in the TERMINATING or TERMINATED states. */ QUIC_TERMINATE_CAUSE terminate_cause; @@ -324,6 +292,8 @@ struct quic_channel_st { /* We have received transport parameters from the peer. */ unsigned int got_remote_transport_params : 1; + /* We have generated our local transport parameters. */ + unsigned int got_local_transport_params : 1; /* * This monotonically transitions to 1 once the TLS state machine is @@ -458,18 +428,24 @@ struct quic_channel_st { */ unsigned int protocol_error : 1; - /* Inhibit tick for testing purposes? */ - unsigned int inhibit_tick : 1; - /* Are we using addressed mode? */ unsigned int addressed_mode : 1; + /* Are we on the QUIC_PORT linked list of channels? */ + unsigned int on_port_list : 1; + + /* Has qlog been requested? */ + unsigned int use_qlog : 1; + /* Saved error stack in case permanent error was encountered */ ERR_STATE *err_state; /* Scratch area for use by RXDP to store decoded ACK ranges. */ OSSL_QUIC_ACK_RANGE *ack_range_scratch; size_t num_ack_range_scratch; + + /* Title for qlog purposes. We own this copy. */ + char *qlog_title; }; # endif diff --git a/libs/openssl-3/ssl/quic/quic_demux.c b/libs/openssl-3/ssl/quic/quic_demux.c index 88135fe5b..e3b5ca191 100644 --- a/libs/openssl-3/ssl/quic/quic_demux.c +++ b/libs/openssl-3/ssl/quic/quic_demux.c @@ -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 @@ -21,37 +21,6 @@ #define DEMUX_DEFAULT_MTU 1500 -/* Structure used to track a given connection ID. */ -typedef struct quic_demux_conn_st QUIC_DEMUX_CONN; - -struct quic_demux_conn_st { - QUIC_DEMUX_CONN *next; /* used when unregistering only */ - QUIC_CONN_ID dst_conn_id; - ossl_quic_demux_cb_fn *cb; - void *cb_arg; -}; - -DEFINE_LHASH_OF_EX(QUIC_DEMUX_CONN); - -static unsigned long demux_conn_hash(const QUIC_DEMUX_CONN *conn) -{ - size_t i; - unsigned long v = 0; - - assert(conn->dst_conn_id.id_len <= QUIC_MAX_CONN_ID_LEN); - - for (i = 0; i < conn->dst_conn_id.id_len; ++i) - v ^= ((unsigned long)conn->dst_conn_id.id[i]) - << ((i * 8) % (sizeof(unsigned long) * 8)); - - return v; -} - -static int demux_conn_cmp(const QUIC_DEMUX_CONN *a, const QUIC_DEMUX_CONN *b) -{ - return !ossl_quic_conn_id_eq(&a->dst_conn_id, &b->dst_conn_id); -} - struct quic_demux_st { /* The underlying transport BIO with datagram semantics. */ BIO *net_bio; @@ -69,21 +38,17 @@ struct quic_demux_st { */ size_t mtu; + /* The datagram_id to use for the next datagram we receive. */ + uint64_t next_datagram_id; + /* Time retrieval callback. */ OSSL_TIME (*now)(void *arg); void *now_arg; - /* Hashtable mapping connection IDs to QUIC_DEMUX_CONN structures. */ - LHASH_OF(QUIC_DEMUX_CONN) *conns_by_id; - /* The default packet handler, if any. */ ossl_quic_demux_cb_fn *default_cb; void *default_cb_arg; - /* The stateless reset token checker handler, if any. */ - ossl_quic_stateless_reset_cb_fn *reset_token_cb; - void *reset_token_cb_arg; - /* * List of URXEs which are not currently in use (i.e., not filled with * unconsumed data). These are moved to the pending list as they are filled. @@ -121,13 +86,6 @@ QUIC_DEMUX *ossl_quic_demux_new(BIO *net_bio, demux->now = now; demux->now_arg = now_arg; - demux->conns_by_id - = lh_QUIC_DEMUX_CONN_new(demux_conn_hash, demux_conn_cmp); - if (demux->conns_by_id == NULL) { - OPENSSL_free(demux); - return NULL; - } - if (net_bio != NULL && BIO_dgram_get_local_addr_cap(net_bio) && BIO_dgram_set_local_addr_enable(net_bio, 1)) @@ -136,11 +94,6 @@ QUIC_DEMUX *ossl_quic_demux_new(BIO *net_bio, return demux; } -static void demux_free_conn_it(QUIC_DEMUX_CONN *conn, void *arg) -{ - OPENSSL_free(conn); -} - static void demux_free_urxl(QUIC_URXE_LIST *l) { QUIC_URXE *e, *enext; @@ -157,10 +110,6 @@ void ossl_quic_demux_free(QUIC_DEMUX *demux) if (demux == NULL) return; - /* Free all connection structures. */ - lh_QUIC_DEMUX_CONN_doall_arg(demux->conns_by_id, demux_free_conn_it, NULL); - lh_QUIC_DEMUX_CONN_free(demux->conns_by_id); - /* Free all URXEs we are holding. */ demux_free_urxl(&demux->urx_free); demux_free_urxl(&demux->urx_pending); @@ -195,104 +144,6 @@ int ossl_quic_demux_set_mtu(QUIC_DEMUX *demux, unsigned int mtu) return 1; } -static QUIC_DEMUX_CONN *demux_get_by_conn_id(QUIC_DEMUX *demux, - const QUIC_CONN_ID *dst_conn_id) -{ - QUIC_DEMUX_CONN key; - - if (dst_conn_id->id_len > QUIC_MAX_CONN_ID_LEN) - return NULL; - - key.dst_conn_id = *dst_conn_id; - return lh_QUIC_DEMUX_CONN_retrieve(demux->conns_by_id, &key); -} - -int ossl_quic_demux_register(QUIC_DEMUX *demux, - const QUIC_CONN_ID *dst_conn_id, - ossl_quic_demux_cb_fn *cb, void *cb_arg) -{ - QUIC_DEMUX_CONN *conn; - - if (dst_conn_id == NULL - || dst_conn_id->id_len > QUIC_MAX_CONN_ID_LEN - || cb == NULL) - return 0; - - /* Ensure not already registered. */ - if (demux_get_by_conn_id(demux, dst_conn_id) != NULL) - /* Handler already registered with this connection ID. */ - return 0; - - conn = OPENSSL_zalloc(sizeof(QUIC_DEMUX_CONN)); - if (conn == NULL) - return 0; - - conn->dst_conn_id = *dst_conn_id; - conn->cb = cb; - conn->cb_arg = cb_arg; - - lh_QUIC_DEMUX_CONN_insert(demux->conns_by_id, conn); - return 1; -} - -static void demux_unregister(QUIC_DEMUX *demux, - QUIC_DEMUX_CONN *conn) -{ - lh_QUIC_DEMUX_CONN_delete(demux->conns_by_id, conn); - OPENSSL_free(conn); -} - -int ossl_quic_demux_unregister(QUIC_DEMUX *demux, - const QUIC_CONN_ID *dst_conn_id) -{ - QUIC_DEMUX_CONN *conn; - - if (dst_conn_id == NULL - || dst_conn_id->id_len > QUIC_MAX_CONN_ID_LEN) - return 0; - - conn = demux_get_by_conn_id(demux, dst_conn_id); - if (conn == NULL) - return 0; - - demux_unregister(demux, conn); - return 1; -} - -struct unreg_arg { - ossl_quic_demux_cb_fn *cb; - void *cb_arg; - QUIC_DEMUX_CONN *head; -}; - -static void demux_unregister_by_cb(QUIC_DEMUX_CONN *conn, void *arg_) -{ - struct unreg_arg *arg = arg_; - - if (conn->cb == arg->cb && conn->cb_arg == arg->cb_arg) { - conn->next = arg->head; - arg->head = conn; - } -} - -void ossl_quic_demux_unregister_by_cb(QUIC_DEMUX *demux, - ossl_quic_demux_cb_fn *cb, - void *cb_arg) -{ - QUIC_DEMUX_CONN *conn, *cnext; - struct unreg_arg arg = {0}; - arg.cb = cb; - arg.cb_arg = cb_arg; - - lh_QUIC_DEMUX_CONN_doall_arg(demux->conns_by_id, - demux_unregister_by_cb, &arg); - - for (conn = arg.head; conn != NULL; conn = cnext) { - cnext = conn->next; - demux_unregister(demux, conn); - } -} - void ossl_quic_demux_set_default_handler(QUIC_DEMUX *demux, ossl_quic_demux_cb_fn *cb, void *cb_arg) @@ -301,14 +152,6 @@ void ossl_quic_demux_set_default_handler(QUIC_DEMUX *demux, demux->default_cb_arg = cb_arg; } -void ossl_quic_demux_set_stateless_reset_handler( - QUIC_DEMUX *demux, - ossl_quic_stateless_reset_cb_fn *cb, void *cb_arg) -{ - demux->reset_token_cb = cb; - demux->reset_token_cb_arg = cb_arg; -} - static QUIC_URXE *demux_alloc_urxe(size_t alloc_len) { QUIC_URXE *e; @@ -460,6 +303,7 @@ static int demux_recv(QUIC_DEMUX *demux) urxe->data_len = msg[i].data_len; /* Time we received datagram. */ urxe->time = now; + urxe->datagram_id = demux->next_datagram_id++; /* Move from free list to pending list. */ ossl_list_urxe_remove(&demux->urx_free, urxe); ossl_list_urxe_insert_tail(&demux->urx_pending, urxe); @@ -480,29 +324,14 @@ static int demux_identify_conn_id(QUIC_DEMUX *demux, dst_conn_id); } -/* Identify the connection structure corresponding to a given URXE. */ -static QUIC_DEMUX_CONN *demux_identify_conn(QUIC_DEMUX *demux, QUIC_URXE *e) -{ - QUIC_CONN_ID dst_conn_id; - - if (!demux_identify_conn_id(demux, e, &dst_conn_id)) - /* - * Datagram is so badly malformed we can't get the DCID from the first - * packet in it, so just give up. - */ - return NULL; - - return demux_get_by_conn_id(demux, &dst_conn_id); -} - /* * Process a single pending URXE. - * Returning 1 on success, 0 on failure and -1 on stateless reset. + * Returning 1 on success, 0 on failure. */ static int demux_process_pending_urxe(QUIC_DEMUX *demux, QUIC_URXE *e) { - QUIC_DEMUX_CONN *conn; - int r; + QUIC_CONN_ID dst_conn_id; + int dst_conn_id_ok = 0; /* The next URXE we process should be at the head of the pending list. */ if (!ossl_assert(e == ossl_list_urxe_head(&demux->urx_pending))) @@ -510,57 +339,25 @@ static int demux_process_pending_urxe(QUIC_DEMUX *demux, QUIC_URXE *e) assert(e->demux_state == URXE_DEMUX_STATE_PENDING); - /* - * Check if the packet ends with a stateless reset token and if it does - * skip it after dropping the connection. - * - * RFC 9000 s. 10.3.1 Detecting a Stateless Reset - * If the last 16 bytes of the datagram are identical in value to - * a stateless reset token, the endpoint MUST enter the draining - * period and not send any further packets on this connection. - * - * Returning a failure here causes the connection to enter the terminating - * state which achieves the desired outcome. - * - * TODO(QUIC FUTURE): only try to match unparsable packets - */ - if (demux->reset_token_cb != NULL) { - r = demux->reset_token_cb(ossl_quic_urxe_data(e), e->data_len, - demux->reset_token_cb_arg); - if (r > 0) /* Received a stateless reset */ - return -1; - if (r < 0) /* Error during stateless reset detection */ - return 0; - } + /* Determine the DCID of the first packet in the datagram. */ + dst_conn_id_ok = demux_identify_conn_id(demux, e, &dst_conn_id); - conn = demux_identify_conn(demux, e); - if (conn == NULL) { + ossl_list_urxe_remove(&demux->urx_pending, e); + if (demux->default_cb != NULL) { /* - * We could not identify a connection. If we have a default packet - * handler, pass it to the handler. Otherwise, we will never be able to - * process this datagram, so get rid of it. + * Pass to default handler for routing. The URXE now belongs to the + * callback. */ - ossl_list_urxe_remove(&demux->urx_pending, e); - if (demux->default_cb != NULL) { - /* Pass to default handler. */ - e->demux_state = URXE_DEMUX_STATE_ISSUED; - demux->default_cb(e, demux->default_cb_arg); - } else { - /* Discard. */ - ossl_list_urxe_insert_tail(&demux->urx_free, e); - e->demux_state = URXE_DEMUX_STATE_FREE; - } - return 1; /* keep processing pending URXEs */ + e->demux_state = URXE_DEMUX_STATE_ISSUED; + demux->default_cb(e, demux->default_cb_arg, + dst_conn_id_ok ? &dst_conn_id : NULL); + } else { + /* Discard. */ + ossl_list_urxe_insert_tail(&demux->urx_free, e); + e->demux_state = URXE_DEMUX_STATE_FREE; } - /* - * Remove from list and invoke callback. The URXE now belongs to the - * callback. (QUIC_DEMUX_CONN never has non-NULL cb.) - */ - ossl_list_urxe_remove(&demux->urx_pending, e); - e->demux_state = URXE_DEMUX_STATE_ISSUED; - conn->cb(e, conn->cb_arg); - return 1; + return 1; /* keep processing pending URXEs */ } /* Process pending URXEs to generate callbacks. */ @@ -600,8 +397,7 @@ int ossl_quic_demux_pump(QUIC_DEMUX *demux) } if ((ret = demux_process_pending_urxl(demux)) <= 0) - return ret == 0 ? QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL - : QUIC_DEMUX_PUMP_RES_STATELESS_RESET; + return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; return QUIC_DEMUX_PUMP_RES_OK; } diff --git a/libs/openssl-3/ssl/quic/quic_engine.c b/libs/openssl-3/ssl/quic/quic_engine.c new file mode 100644 index 000000000..3bcb5d681 --- /dev/null +++ b/libs/openssl-3/ssl/quic/quic_engine.c @@ -0,0 +1,140 @@ +/* + * 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 + */ + +#include "internal/quic_engine.h" +#include "internal/quic_port.h" +#include "quic_engine_local.h" +#include "quic_port_local.h" +#include "../ssl_local.h" + +/* + * QUIC Engine + * =========== + */ +static int qeng_init(QUIC_ENGINE *qeng); +static void qeng_cleanup(QUIC_ENGINE *qeng); +static void qeng_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags); + +DEFINE_LIST_OF_IMPL(port, QUIC_PORT); + +QUIC_ENGINE *ossl_quic_engine_new(const QUIC_ENGINE_ARGS *args) +{ + QUIC_ENGINE *qeng; + + if ((qeng = OPENSSL_zalloc(sizeof(QUIC_ENGINE))) == NULL) + return NULL; + + qeng->libctx = args->libctx; + qeng->propq = args->propq; + qeng->mutex = args->mutex; + qeng->now_cb = args->now_cb; + qeng->now_cb_arg = args->now_cb_arg; + + if (!qeng_init(qeng)) { + OPENSSL_free(qeng); + return NULL; + } + + return qeng; +} + +void ossl_quic_engine_free(QUIC_ENGINE *qeng) +{ + if (qeng == NULL) + return; + + qeng_cleanup(qeng); + OPENSSL_free(qeng); +} + +static int qeng_init(QUIC_ENGINE *qeng) +{ + ossl_quic_reactor_init(&qeng->rtor, qeng_tick, qeng, ossl_time_zero()); + return 1; +} + +static void qeng_cleanup(QUIC_ENGINE *qeng) +{ + assert(ossl_list_port_num(&qeng->port_list) == 0); +} + +QUIC_REACTOR *ossl_quic_engine_get0_reactor(QUIC_ENGINE *qeng) +{ + return &qeng->rtor; +} + +CRYPTO_MUTEX *ossl_quic_engine_get0_mutex(QUIC_ENGINE *qeng) +{ + return qeng->mutex; +} + +OSSL_TIME ossl_quic_engine_get_time(QUIC_ENGINE *qeng) +{ + if (qeng->now_cb == NULL) + return ossl_time_now(); + + return qeng->now_cb(qeng->now_cb_arg); +} + +void ossl_quic_engine_set_inhibit_tick(QUIC_ENGINE *qeng, int inhibit) +{ + qeng->inhibit_tick = (inhibit != 0); +} + +/* + * QUIC Engine: Child Object Lifecycle Management + * ============================================== + */ + +QUIC_PORT *ossl_quic_engine_create_port(QUIC_ENGINE *qeng, + const QUIC_PORT_ARGS *args) +{ + QUIC_PORT_ARGS largs = *args; + + if (ossl_list_port_num(&qeng->port_list) > 0) + /* TODO(QUIC MULTIPORT): We currently support only one port. */ + return NULL; + + if (largs.engine != NULL) + return NULL; + + largs.engine = qeng; + return ossl_quic_port_new(&largs); +} + +/* + * QUIC Engine: Ticker-Mutator + * ========================== + */ + +/* + * The central ticker function called by the reactor. This does everything, or + * at least everything network I/O related. Best effort - not allowed to fail + * "loudly". + */ +static void qeng_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) +{ + QUIC_ENGINE *qeng = arg; + QUIC_PORT *port; + + res->net_read_desired = 0; + res->net_write_desired = 0; + res->tick_deadline = ossl_time_infinite(); + + if (qeng->inhibit_tick) + return; + + /* Iterate through all ports and service them. */ + LIST_FOREACH(port, port, &qeng->port_list) { + QUIC_TICK_RESULT subr = {0}; + + ossl_quic_port_subtick(port, &subr, flags); + ossl_quic_tick_result_merge_into(res, &subr); + } +} diff --git a/libs/openssl-3/ssl/quic/quic_engine_local.h b/libs/openssl-3/ssl/quic/quic_engine_local.h new file mode 100644 index 000000000..280fd31dd --- /dev/null +++ b/libs/openssl-3/ssl/quic/quic_engine_local.h @@ -0,0 +1,59 @@ +/* + * 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_LOCAL_H +# define OSSL_QUIC_ENGINE_LOCAL_H + +# include "internal/quic_engine.h" +# include "internal/quic_reactor.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Engine Structure + * ===================== + * + * QUIC engine internals. It is intended that only the QUIC_ENGINE, QUIC_PORT + * and QUIC_CHANNEL implementations be allowed to access this structure + * directly. + * + * Other components should not include this header. + */ +DECLARE_LIST_OF(port, QUIC_PORT); + +struct quic_engine_st { + /* All objects in a QUIC event domain share the same (libctx, propq). */ + OSSL_LIB_CTX *libctx; + const char *propq; + + /* + * Master synchronisation mutex for the entire QUIC event domain. Used for + * thread assisted mode synchronisation. We don't own this; the instantiator + * of the engine passes it to us and is responsible for freeing it after + * engine destruction. + */ + CRYPTO_MUTEX *mutex; + + /* Callback used to get the current time. */ + OSSL_TIME (*now_cb)(void *arg); + void *now_cb_arg; + + /* Asynchronous I/O reactor. */ + QUIC_REACTOR rtor; + + /* List of all child ports. */ + OSSL_LIST(port) port_list; + + /* Inhibit tick for testing purposes? */ + unsigned int inhibit_tick : 1; +}; + +# endif + +#endif diff --git a/libs/openssl-3/ssl/quic/quic_fc.c b/libs/openssl-3/ssl/quic/quic_fc.c index 750e89630..64ef31780 100644 --- a/libs/openssl-3/ssl/quic/quic_fc.c +++ b/libs/openssl-3/ssl/quic/quic_fc.c @@ -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 @@ -189,7 +189,7 @@ static int on_rx_controlled_bytes(QUIC_RXFC *rxfc, uint64_t num_bytes) if (num_bytes > credit) { ok = 0; num_bytes = credit; - rxfc->error_code = QUIC_ERR_FLOW_CONTROL_ERROR; + rxfc->error_code = OSSL_QUIC_ERR_FLOW_CONTROL_ERROR; } rxfc->swm += num_bytes; @@ -205,7 +205,7 @@ int ossl_quic_rxfc_on_rx_stream_frame(QUIC_RXFC *rxfc, uint64_t end, int is_fin) if (rxfc->is_fin && ((is_fin && rxfc->hwm != end) || end > rxfc->hwm)) { /* Stream size cannot change after the stream is finished */ - rxfc->error_code = QUIC_ERR_FINAL_SIZE_ERROR; + rxfc->error_code = OSSL_QUIC_ERR_FINAL_SIZE_ERROR; return 1; /* not a caller error */ } @@ -220,7 +220,7 @@ int ossl_quic_rxfc_on_rx_stream_frame(QUIC_RXFC *rxfc, uint64_t end, int is_fin) if (rxfc->parent != NULL) on_rx_controlled_bytes(rxfc->parent, delta); /* result ignored */ } else if (end < rxfc->hwm && is_fin) { - rxfc->error_code = QUIC_ERR_FINAL_SIZE_ERROR; + rxfc->error_code = OSSL_QUIC_ERR_FINAL_SIZE_ERROR; return 1; /* not a caller error */ } @@ -359,21 +359,26 @@ int ossl_quic_rxfc_on_retire(QUIC_RXFC *rxfc, return 1; } -uint64_t ossl_quic_rxfc_get_cwm(QUIC_RXFC *rxfc) +uint64_t ossl_quic_rxfc_get_cwm(const QUIC_RXFC *rxfc) { return rxfc->cwm; } -uint64_t ossl_quic_rxfc_get_swm(QUIC_RXFC *rxfc) +uint64_t ossl_quic_rxfc_get_swm(const QUIC_RXFC *rxfc) { return rxfc->swm; } -uint64_t ossl_quic_rxfc_get_rwm(QUIC_RXFC *rxfc) +uint64_t ossl_quic_rxfc_get_rwm(const QUIC_RXFC *rxfc) { return rxfc->rwm; } +uint64_t ossl_quic_rxfc_get_credit(const QUIC_RXFC *rxfc) +{ + return ossl_quic_rxfc_get_cwm(rxfc) - ossl_quic_rxfc_get_swm(rxfc); +} + int ossl_quic_rxfc_has_cwm_changed(QUIC_RXFC *rxfc, int clear) { int r = rxfc->has_cwm_changed; diff --git a/libs/openssl-3/ssl/quic/quic_fifd.c b/libs/openssl-3/ssl/quic/quic_fifd.c index a3dd1db97..1d1bcc11c 100644 --- a/libs/openssl-3/ssl/quic/quic_fifd.c +++ b/libs/openssl-3/ssl/quic/quic_fifd.c @@ -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 @@ -9,6 +9,7 @@ #include "internal/quic_fifd.h" #include "internal/quic_wire.h" +#include "internal/qlog_event_helpers.h" DEFINE_LIST_OF(tx_history, OSSL_ACKM_TX_PKT); @@ -34,7 +35,9 @@ int ossl_quic_fifd_init(QUIC_FIFD *fifd, void *confirm_frame_arg, void (*sstream_updated)(uint64_t stream_id, void *arg), - void *sstream_updated_arg) + void *sstream_updated_arg, + QLOG *(*get_qlog_cb)(void *arg), + void *get_qlog_cb_arg) { if (cfq == NULL || ackm == NULL || txpim == NULL || get_sstream_by_id == NULL || regen_frame == NULL) @@ -51,6 +54,8 @@ int ossl_quic_fifd_init(QUIC_FIFD *fifd, fifd->confirm_frame_arg = confirm_frame_arg; fifd->sstream_updated = sstream_updated; fifd->sstream_updated_arg = sstream_updated_arg; + fifd->get_qlog_cb = get_qlog_cb; + fifd->get_qlog_cb_arg = get_qlog_cb_arg; return 1; } @@ -107,6 +112,14 @@ static void on_acked(void *arg) ossl_quic_txpim_pkt_release(fifd->txpim, pkt); } +static QLOG *fifd_get_qlog(QUIC_FIFD *fifd) +{ + if (fifd->get_qlog_cb == NULL) + return NULL; + + return fifd->get_qlog_cb(fifd->get_qlog_cb_arg); +} + static void on_lost(void *arg) { QUIC_TXPIM_PKT *pkt = arg; @@ -117,6 +130,8 @@ static void on_lost(void *arg) QUIC_CFQ_ITEM *cfq_item, *cfq_item_next; int sstream_updated; + ossl_qlog_event_recovery_packet_lost(fifd_get_qlog(fifd), pkt); + /* STREAM and CRYPTO stream chunks, FIN and stream FC frames */ for (i = 0; i < num_chunks; ++i) { sstream = fifd->get_sstream_by_id(chunks[i].stream_id, @@ -288,3 +303,10 @@ int ossl_quic_fifd_pkt_commit(QUIC_FIFD *fifd, QUIC_TXPIM_PKT *pkt) /* Inform the ACKM. */ return ossl_ackm_on_tx_packet(fifd->ackm, &pkt->ackm_pkt); } + +void ossl_quic_fifd_set_qlog_cb(QUIC_FIFD *fifd, QLOG *(*get_qlog_cb)(void *arg), + void *get_qlog_cb_arg) +{ + fifd->get_qlog_cb = get_qlog_cb; + fifd->get_qlog_cb_arg = get_qlog_cb_arg; +} diff --git a/libs/openssl-3/ssl/quic/quic_impl.c b/libs/openssl-3/ssl/quic/quic_impl.c index 399d1d2af..c77230a19 100644 --- a/libs/openssl-3/ssl/quic/quic_impl.c +++ b/libs/openssl-3/ssl/quic/quic_impl.c @@ -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 @@ -15,6 +15,8 @@ #include "internal/quic_tls.h" #include "internal/quic_rx_depack.h" #include "internal/quic_error.h" +#include "internal/quic_engine.h" +#include "internal/quic_port.h" #include "internal/time.h" typedef struct qctx_st QCTX; @@ -23,7 +25,7 @@ static void aon_write_finish(QUIC_XSO *xso); static int create_channel(QUIC_CONNECTION *qc); static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs); static int qc_try_create_default_xso_for_write(QCTX *ctx); -static int qc_wait_for_default_xso_for_read(QCTX *ctx); +static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek); static void quic_lock(QUIC_CONNECTION *qc); static void quic_unlock(QUIC_CONNECTION *qc); static void quic_lock_for_io(QCTX *ctx); @@ -38,6 +40,8 @@ static int quic_validate_for_write(QUIC_XSO *xso, int *err); static int quic_mutation_allowed(QUIC_CONNECTION *qc, int req_active); static int qc_blocking_mode(const QUIC_CONNECTION *qc); static int xso_blocking_mode(const QUIC_XSO *xso); +static void qctx_maybe_autotick(QCTX *ctx); +static int qctx_should_autotick(QCTX *ctx); /* * QUIC Front-End I/O API: Common Utilities @@ -63,7 +67,7 @@ static int block_until_pred(QUIC_CONNECTION *qc, * Any attempt to block auto-disables tick inhibition as otherwise we will * hang around forever. */ - ossl_quic_channel_set_inhibit_tick(qc->ch, 0); + ossl_quic_engine_set_inhibit_tick(qc->engine, 0); rtor = ossl_quic_channel_get_reactor(qc->ch); return ossl_quic_reactor_block_until_pred(rtor, pred, pred_arg, flags, @@ -264,7 +268,7 @@ static int ossl_unused expect_quic_with_stream_lock(const SSL *s, int remote_ini if (!qc_try_create_default_xso_for_write(ctx)) goto err; } else { - if (!qc_wait_for_default_xso_for_read(ctx)) + if (!qc_wait_for_default_xso_for_read(ctx, /*peek=*/0)) goto err; } @@ -451,7 +455,7 @@ SSL *ossl_quic_new(SSL_CTX *ctx) err: if (ssl_base == NULL) { #if defined(OPENSSL_THREADS) - ossl_crypto_mutex_free(qc->mutex); + ossl_crypto_mutex_free(&qc->mutex); #endif OPENSSL_free(qc); } else { @@ -542,18 +546,24 @@ void ossl_quic_free(SSL *s) } #endif + SSL_free(ctx.qc->tls); + ossl_quic_channel_free(ctx.qc->ch); + ossl_quic_port_free(ctx.qc->port); + ossl_quic_engine_free(ctx.qc->engine); BIO_free_all(ctx.qc->net_rbio); BIO_free_all(ctx.qc->net_wbio); - /* Note: SSL_free calls OPENSSL_free(qc) for us */ - - SSL_free(ctx.qc->tls); quic_unlock(ctx.qc); /* tsan doesn't like freeing locked mutexes */ #if defined(OPENSSL_THREADS) ossl_crypto_mutex_free(&ctx.qc->mutex); #endif + + /* + * Note: SSL_free (that called this function) calls OPENSSL_free(ctx.qc) for + * us + */ } /* SSL method init */ @@ -854,7 +864,7 @@ static int qc_can_support_blocking_cached(QUIC_CONNECTION *qc) static void qc_update_can_support_blocking(QUIC_CONNECTION *qc) { - ossl_quic_channel_update_poll_descriptors(qc->ch); /* best effort */ + ossl_quic_port_update_poll_descriptors(qc->port); /* best effort */ } static void qc_update_blocking_mode(QUIC_CONNECTION *qc) @@ -872,7 +882,7 @@ void ossl_quic_conn_set0_net_rbio(SSL *s, BIO *net_rbio) if (ctx.qc->net_rbio == net_rbio) return; - if (!ossl_quic_channel_set_net_rbio(ctx.qc->ch, net_rbio)) + if (!ossl_quic_port_set_net_rbio(ctx.qc->port, net_rbio)) return; BIO_free_all(ctx.qc->net_rbio); @@ -899,7 +909,7 @@ void ossl_quic_conn_set0_net_wbio(SSL *s, BIO *net_wbio) if (ctx.qc->net_wbio == net_wbio) return; - if (!ossl_quic_channel_set_net_wbio(ctx.qc->ch, net_wbio)) + if (!ossl_quic_port_set_net_wbio(ctx.qc->port, net_wbio)) return; BIO_free_all(ctx.qc->net_wbio); @@ -1262,7 +1272,7 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags, goto err; } } else { - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + qctx_maybe_autotick(&ctx); } } @@ -1281,7 +1291,7 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags, goto err; } } else { - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + qctx_maybe_autotick(&ctx); } if (!ossl_quic_channel_is_term_any(ctx.qc->ch)) { @@ -1322,7 +1332,7 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags, goto err; } } else { - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + qctx_maybe_autotick(&ctx); } ret = ossl_quic_channel_is_terminated(ctx.qc->ch); @@ -1476,8 +1486,8 @@ static int configure_channel(QUIC_CONNECTION *qc) { assert(qc->ch != NULL); - if (!ossl_quic_channel_set_net_rbio(qc->ch, qc->net_rbio) - || !ossl_quic_channel_set_net_wbio(qc->ch, qc->net_wbio) + if (!ossl_quic_port_set_net_rbio(qc->port, qc->net_rbio) + || !ossl_quic_port_set_net_wbio(qc->port, qc->net_wbio) || !ossl_quic_channel_set_peer_addr(qc->ch, &qc->init_peer_addr)) return 0; @@ -1487,19 +1497,33 @@ static int configure_channel(QUIC_CONNECTION *qc) QUIC_NEEDS_LOCK static int create_channel(QUIC_CONNECTION *qc) { - QUIC_CHANNEL_ARGS args = {0}; + QUIC_ENGINE_ARGS engine_args = {0}; + QUIC_PORT_ARGS port_args = {0}; + + engine_args.libctx = qc->ssl.ctx->libctx; + engine_args.propq = qc->ssl.ctx->propq; + engine_args.mutex = qc->mutex; + engine_args.now_cb = get_time_cb; + engine_args.now_cb_arg = qc; + qc->engine = ossl_quic_engine_new(&engine_args); + if (qc->engine == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + return 0; + } - args.libctx = qc->ssl.ctx->libctx; - args.propq = qc->ssl.ctx->propq; - args.is_server = qc->as_server; - args.tls = qc->tls; - args.mutex = qc->mutex; - args.now_cb = get_time_cb; - args.now_cb_arg = qc; + port_args.channel_ctx = qc->ssl.ctx; + qc->port = ossl_quic_engine_create_port(qc->engine, &port_args); + if (qc->port == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + ossl_quic_engine_free(qc->engine); + return 0; + } - qc->ch = ossl_quic_channel_new(&args); + qc->ch = ossl_quic_port_create_outgoing(qc->port, qc->tls); if (qc->ch == NULL) { QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + ossl_quic_port_free(qc->port); + ossl_quic_engine_free(qc->engine); return 0; } @@ -1656,7 +1680,7 @@ static int quic_do_handshake(QCTX *ctx) if (!qc_blocking_mode(qc)) { /* Try to advance the reactor. */ - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0); + qctx_maybe_autotick(ctx); if (ossl_quic_channel_is_handshake_complete(qc->ch)) /* The handshake is now done. */ @@ -1827,7 +1851,7 @@ static int quic_wait_for_stream(void *arg) } QUIC_NEEDS_LOCK -static int qc_wait_for_default_xso_for_read(QCTX *ctx) +static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek) { /* Called on a QCSO and we don't currently have a default stream. */ uint64_t expect_id; @@ -1862,13 +1886,16 @@ static int qc_wait_for_default_xso_for_read(QCTX *ctx) expect_id | QUIC_STREAM_DIR_UNI); if (qs == NULL) { - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0); + qctx_maybe_autotick(ctx); qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch), expect_id); } if (qs == NULL) { + if (peek) + return 0; + if (!qc_blocking_mode(qc)) /* Non-blocking mode, so just bail immediately. */ return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_READ); @@ -2148,7 +2175,9 @@ int ossl_quic_want(const SSL *s) * */ QUIC_NEEDS_LOCK -static void quic_post_write(QUIC_XSO *xso, int did_append, int do_tick) +static void quic_post_write(QUIC_XSO *xso, int did_append, + int did_append_all, uint64_t flags, + int do_tick) { /* * We have appended at least one byte to the stream. @@ -2158,6 +2187,9 @@ static void quic_post_write(QUIC_XSO *xso, int did_append, int do_tick) ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(xso->conn->ch), xso->stream); + if (did_append_all && (flags & SSL_WRITE_FLAG_CONCLUDE) != 0) + ossl_quic_sstream_fin(xso->stream->sstream); + /* * Try and send. * @@ -2174,6 +2206,7 @@ struct quic_write_again_args { size_t len; size_t total_written; int err; + uint64_t flags; }; /* @@ -2249,7 +2282,8 @@ static int quic_write_again(void *arg) if (!xso_sstream_append(args->xso, args->buf, args->len, &actual_written)) return -2; - quic_post_write(args->xso, actual_written > 0, 0); + quic_post_write(args->xso, actual_written > 0, + args->len == actual_written, args->flags, 0); args->buf += actual_written; args->len -= actual_written; @@ -2265,7 +2299,7 @@ static int quic_write_again(void *arg) QUIC_NEEDS_LOCK static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len, - size_t *written) + uint64_t flags, size_t *written) { int res; QUIC_XSO *xso = ctx->xso; @@ -2279,7 +2313,7 @@ static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len, return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); } - quic_post_write(xso, actual_written > 0, 1); + quic_post_write(xso, actual_written > 0, actual_written == len, flags, 1); if (actual_written == len) { /* Managed to append everything on the first try. */ @@ -2297,6 +2331,7 @@ static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len, args.len = len - actual_written; args.total_written = 0; args.err = ERR_R_INTERNAL_ERROR; + args.flags = flags; res = block_until_pred(xso->conn, quic_write_again, &args, 0); if (res <= 0) { @@ -2335,7 +2370,8 @@ static void aon_write_finish(QUIC_XSO *xso) QUIC_NEEDS_LOCK static int quic_write_nonblocking_aon(QCTX *ctx, const void *buf, - size_t len, size_t *written) + size_t len, uint64_t flags, + size_t *written) { QUIC_XSO *xso = ctx->xso; const void *actual_buf; @@ -2372,7 +2408,8 @@ static int quic_write_nonblocking_aon(QCTX *ctx, const void *buf, return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); } - quic_post_write(xso, actual_written > 0, 1); + quic_post_write(xso, actual_written > 0, actual_written == actual_len, + flags, qctx_should_autotick(ctx)); if (actual_written == actual_len) { /* We have sent everything. */ @@ -2422,7 +2459,7 @@ static int quic_write_nonblocking_aon(QCTX *ctx, const void *buf, QUIC_NEEDS_LOCK static int quic_write_nonblocking_epw(QCTX *ctx, const void *buf, size_t len, - size_t *written) + uint64_t flags, size_t *written) { QUIC_XSO *xso = ctx->xso; @@ -2433,7 +2470,13 @@ static int quic_write_nonblocking_epw(QCTX *ctx, const void *buf, size_t len, return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); } - quic_post_write(xso, *written > 0, 1); + quic_post_write(xso, *written > 0, *written == len, flags, + qctx_should_autotick(ctx)); + + if (*written == 0) + /* SSL_write_ex returns 0 if it didn't read anything. */ + return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_READ); + return 1; } @@ -2480,7 +2523,8 @@ static int quic_validate_for_write(QUIC_XSO *xso, int *err) } QUIC_TAKES_LOCK -int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written) +int ossl_quic_write_flags(SSL *s, const void *buf, size_t len, + uint64_t flags, size_t *written) { int ret; QCTX ctx; @@ -2488,10 +2532,24 @@ int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written) *written = 0; - if (!expect_quic_with_stream_lock(s, /*remote_init=*/0, /*io=*/1, &ctx)) - return 0; + if (len == 0) { + /* Do not autocreate default XSO for zero-length writes. */ + if (!expect_quic(s, &ctx)) + return 0; - partial_write = ((ctx.xso->ssl_mode & SSL_MODE_ENABLE_PARTIAL_WRITE) != 0); + quic_lock_for_io(&ctx); + } else { + if (!expect_quic_with_stream_lock(s, /*remote_init=*/0, /*io=*/1, &ctx)) + return 0; + } + + partial_write = ((ctx.xso != NULL) + ? ((ctx.xso->ssl_mode & SSL_MODE_ENABLE_PARTIAL_WRITE) != 0) : 0); + + if ((flags & ~SSL_WRITE_FLAG_CONCLUDE) != 0) { + ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_UNSUPPORTED_WRITE_FLAG, NULL); + goto out; + } if (!quic_mutation_allowed(ctx.qc, /*req_active=*/0)) { ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); @@ -2508,28 +2566,38 @@ int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written) } /* Ensure correct stream state, stream send part not concluded, etc. */ - if (!quic_validate_for_write(ctx.xso, &err)) { + if (len > 0 && !quic_validate_for_write(ctx.xso, &err)) { ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL); goto out; } if (len == 0) { + if ((flags & SSL_WRITE_FLAG_CONCLUDE) != 0) + quic_post_write(ctx.xso, 0, 1, flags, + qctx_should_autotick(&ctx)); + ret = 1; goto out; } if (xso_blocking_mode(ctx.xso)) - ret = quic_write_blocking(&ctx, buf, len, written); + ret = quic_write_blocking(&ctx, buf, len, flags, written); else if (partial_write) - ret = quic_write_nonblocking_epw(&ctx, buf, len, written); + ret = quic_write_nonblocking_epw(&ctx, buf, len, flags, written); else - ret = quic_write_nonblocking_aon(&ctx, buf, len, written); + ret = quic_write_nonblocking_aon(&ctx, buf, len, flags, written); out: quic_unlock(ctx.qc); return ret; } +QUIC_TAKES_LOCK +int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written) +{ + return ossl_quic_write_flags(s, buf, len, 0, written); +} + /* * SSL_read * -------- @@ -2592,10 +2660,12 @@ static int quic_read_actual(QCTX *ctx, QUIC_CONNECTION *qc = ctx->qc; if (!quic_validate_for_read(ctx->xso, &err, &eos)) { - if (eos) + if (eos) { + ctx->xso->retired_fin = 1; return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_ZERO_RETURN); - else + } else { return QUIC_RAISE_NON_NORMAL_ERROR(ctx, err, NULL); + } } if (peek) { @@ -2637,8 +2707,10 @@ static int quic_read_actual(QCTX *ctx, stream); } - if (*bytes_read == 0 && is_fin) + if (*bytes_read == 0 && is_fin) { + ctx->xso->retired_fin = 1; return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_ZERO_RETURN); + } return 1; } @@ -2698,7 +2770,7 @@ static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek * Wait until we get a stream initiated by the peer (blocking mode) or * fail if we don't have one yet (non-blocking mode). */ - if (!qc_wait_for_default_xso_for_read(&ctx)) { + if (!qc_wait_for_default_xso_for_read(&ctx, /*peek=*/0)) { ret = 0; /* error already raised here */ goto out; } @@ -2716,7 +2788,7 @@ static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek * Even though we succeeded, tick the reactor here to ensure we are * handling other aspects of the QUIC connection. */ - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + qctx_maybe_autotick(&ctx); ret = 1; } else if (xso_blocking_mode(ctx.xso)) { /* @@ -2746,7 +2818,7 @@ static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek * We did not get any bytes and are not in blocking mode. * Tick to see if this delivers any more. */ - ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + qctx_maybe_autotick(&ctx); /* Try the read again. */ if (!quic_read_actual(&ctx, ctx.xso->stream, buf, len, bytes_read, peek)) { @@ -2785,8 +2857,6 @@ static size_t ossl_quic_pending_int(const SSL *s, int check_channel) { QCTX ctx; size_t avail = 0; - int fin = 0; - if (!expect_quic(s, &ctx)) return 0; @@ -2794,21 +2864,28 @@ static size_t ossl_quic_pending_int(const SSL *s, int check_channel) quic_lock(ctx.qc); if (ctx.xso == NULL) { - QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_NO_STREAM, NULL); - goto out; + /* No XSO yet, but there might be a default XSO eligible to be created. */ + if (qc_wait_for_default_xso_for_read(&ctx, /*peek=*/1)) { + ctx.xso = ctx.qc->default_xso; + } else { + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_NO_STREAM, NULL); + goto out; + } } - if (ctx.xso->stream == NULL - || !ossl_quic_stream_has_recv_buffer(ctx.xso->stream)) { + if (ctx.xso->stream == NULL) { QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL); goto out; } - if (!ossl_quic_rstream_available(ctx.xso->stream->rstream, &avail, &fin)) - avail = 0; - - if (avail == 0 && check_channel && ossl_quic_channel_has_pending(ctx.qc->ch)) - avail = 1; + if (check_channel) + avail = ossl_quic_stream_recv_pending(ctx.xso->stream, + /*include_fin=*/1) + || ossl_quic_channel_has_pending(ctx.qc->ch) + || ossl_quic_channel_is_term_any(ctx.qc->ch); + else + avail = ossl_quic_stream_recv_pending(ctx.xso->stream, + /*include_fin=*/0); out: quic_unlock(ctx.qc); @@ -2858,7 +2935,7 @@ int ossl_quic_conn_stream_conclude(SSL *s) } ossl_quic_sstream_fin(qs->sstream); - quic_post_write(ctx.xso, 1, 1); + quic_post_write(ctx.xso, 1, 0, 0, qctx_should_autotick(&ctx)); quic_unlock(ctx.qc); return 1; } @@ -3151,6 +3228,292 @@ int ossl_quic_set_incoming_stream_policy(SSL *s, int policy, return ret; } +/* + * SSL_get_value, SSL_set_value + * ---------------------------- + */ +QUIC_TAKES_LOCK +static int qc_getset_idle_timeout(QCTX *ctx, uint32_t class_, + uint64_t *p_value_out, uint64_t *p_value_in) +{ + int ret = 0; + uint64_t value_out = 0, value_in; + + quic_lock(ctx->qc); + + switch (class_) { + case SSL_VALUE_CLASS_FEATURE_REQUEST: + value_out = ossl_quic_channel_get_max_idle_timeout_request(ctx->qc->ch); + + if (p_value_in != NULL) { + value_in = *p_value_in; + if (value_in > OSSL_QUIC_VLINT_MAX) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_PASSED_INVALID_ARGUMENT, + NULL); + goto err; + } + + if (ossl_quic_channel_have_generated_transport_params(ctx->qc->ch)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_FEATURE_NOT_RENEGOTIABLE, + NULL); + goto err; + } + + ossl_quic_channel_set_max_idle_timeout_request(ctx->qc->ch, value_in); + } + break; + + case SSL_VALUE_CLASS_FEATURE_PEER_REQUEST: + case SSL_VALUE_CLASS_FEATURE_NEGOTIATED: + if (p_value_in != NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_OP, + NULL); + goto err; + } + + if (!ossl_quic_channel_is_handshake_complete(ctx->qc->ch)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_FEATURE_NEGOTIATION_NOT_COMPLETE, + NULL); + goto err; + } + + value_out = (class_ == SSL_VALUE_CLASS_FEATURE_NEGOTIATED) + ? ossl_quic_channel_get_max_idle_timeout_actual(ctx->qc->ch) + : ossl_quic_channel_get_max_idle_timeout_peer_request(ctx->qc->ch); + break; + + default: + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS, + NULL); + goto err; + } + + ret = 1; +err: + quic_unlock(ctx->qc); + if (ret && p_value_out != NULL) + *p_value_out = value_out; + + return ret; +} + +QUIC_TAKES_LOCK +static int qc_get_stream_avail(QCTX *ctx, uint32_t class_, + int is_uni, int is_remote, + uint64_t *value) +{ + int ret = 0; + + if (class_ != SSL_VALUE_CLASS_GENERIC) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS, + NULL); + return 0; + } + + quic_lock(ctx->qc); + + *value = is_remote + ? ossl_quic_channel_get_remote_stream_count_avail(ctx->qc->ch, is_uni) + : ossl_quic_channel_get_local_stream_count_avail(ctx->qc->ch, is_uni); + + ret = 1; + quic_unlock(ctx->qc); + return ret; +} + +QUIC_NEEDS_LOCK +static int qctx_should_autotick(QCTX *ctx) +{ + int event_handling_mode; + + if (ctx->is_stream) { + event_handling_mode = ctx->xso->event_handling_mode; + if (event_handling_mode != SSL_VALUE_EVENT_HANDLING_MODE_INHERIT) + return event_handling_mode != SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT; + } + + event_handling_mode = ctx->qc->event_handling_mode; + return event_handling_mode != SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT; +} + +QUIC_NEEDS_LOCK +static void qctx_maybe_autotick(QCTX *ctx) +{ + if (!qctx_should_autotick(ctx)) + return; + + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx->qc->ch), 0); +} + +QUIC_TAKES_LOCK +static int qc_getset_event_handling(QCTX *ctx, uint32_t class_, + uint64_t *p_value_out, + uint64_t *p_value_in) +{ + int ret = 0; + uint64_t value_out = 0; + + quic_lock(ctx->qc); + + if (class_ != SSL_VALUE_CLASS_GENERIC) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS, + NULL); + goto err; + } + + if (p_value_in != NULL) { + switch (*p_value_in) { + case SSL_VALUE_EVENT_HANDLING_MODE_INHERIT: + case SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT: + case SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT: + break; + default: + QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_PASSED_INVALID_ARGUMENT, + NULL); + goto err; + } + + value_out = *p_value_in; + if (ctx->is_stream) + ctx->xso->event_handling_mode = (int)value_out; + else + ctx->qc->event_handling_mode = (int)value_out; + } else { + value_out = ctx->is_stream + ? ctx->xso->event_handling_mode + : ctx->qc->event_handling_mode; + } + + ret = 1; +err: + quic_unlock(ctx->qc); + if (ret && p_value_out != NULL) + *p_value_out = value_out; + + return ret; +} + +QUIC_TAKES_LOCK +static int qc_get_stream_write_buf_stat(QCTX *ctx, uint32_t class_, + uint64_t *p_value_out, + size_t (*getter)(QUIC_SSTREAM *sstream)) +{ + int ret = 0; + size_t value = 0; + + quic_lock(ctx->qc); + + if (class_ != SSL_VALUE_CLASS_GENERIC) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS, + NULL); + goto err; + } + + if (ctx->xso == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_NO_STREAM, NULL); + goto err; + } + + if (!ossl_quic_stream_has_send(ctx->xso->stream)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_STREAM_RECV_ONLY, NULL); + goto err; + } + + if (ossl_quic_stream_has_send_buffer(ctx->xso->stream)) + value = getter(ctx->xso->stream->sstream); + + ret = 1; +err: + quic_unlock(ctx->qc); + *p_value_out = (uint64_t)value; + return ret; +} + +QUIC_NEEDS_LOCK +static int expect_quic_for_value(SSL *s, QCTX *ctx, uint32_t id) +{ + switch (id) { + case SSL_VALUE_EVENT_HANDLING_MODE: + case SSL_VALUE_STREAM_WRITE_BUF_SIZE: + case SSL_VALUE_STREAM_WRITE_BUF_USED: + case SSL_VALUE_STREAM_WRITE_BUF_AVAIL: + return expect_quic(s, ctx); + default: + return expect_quic_conn_only(s, ctx); + } +} + +QUIC_TAKES_LOCK +int ossl_quic_get_value_uint(SSL *s, uint32_t class_, uint32_t id, + uint64_t *value) +{ + QCTX ctx; + + if (!expect_quic_for_value(s, &ctx, id)) + return 0; + + if (value == NULL) + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, + ERR_R_PASSED_INVALID_ARGUMENT, NULL); + + switch (id) { + case SSL_VALUE_QUIC_IDLE_TIMEOUT: + return qc_getset_idle_timeout(&ctx, class_, value, NULL); + + case SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL: + return qc_get_stream_avail(&ctx, class_, /*uni=*/0, /*remote=*/0, value); + case SSL_VALUE_QUIC_STREAM_BIDI_REMOTE_AVAIL: + return qc_get_stream_avail(&ctx, class_, /*uni=*/0, /*remote=*/1, value); + case SSL_VALUE_QUIC_STREAM_UNI_LOCAL_AVAIL: + return qc_get_stream_avail(&ctx, class_, /*uni=*/1, /*remote=*/0, value); + case SSL_VALUE_QUIC_STREAM_UNI_REMOTE_AVAIL: + return qc_get_stream_avail(&ctx, class_, /*uni=*/1, /*remote=*/1, value); + + case SSL_VALUE_EVENT_HANDLING_MODE: + return qc_getset_event_handling(&ctx, class_, value, NULL); + + case SSL_VALUE_STREAM_WRITE_BUF_SIZE: + return qc_get_stream_write_buf_stat(&ctx, class_, value, + ossl_quic_sstream_get_buffer_size); + case SSL_VALUE_STREAM_WRITE_BUF_USED: + return qc_get_stream_write_buf_stat(&ctx, class_, value, + ossl_quic_sstream_get_buffer_used); + case SSL_VALUE_STREAM_WRITE_BUF_AVAIL: + return qc_get_stream_write_buf_stat(&ctx, class_, value, + ossl_quic_sstream_get_buffer_avail); + + default: + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, + SSL_R_UNSUPPORTED_CONFIG_VALUE, NULL); + } + + return 1; +} + +QUIC_TAKES_LOCK +int ossl_quic_set_value_uint(SSL *s, uint32_t class_, uint32_t id, + uint64_t value) +{ + QCTX ctx; + + if (!expect_quic_for_value(s, &ctx, id)) + return 0; + + switch (id) { + case SSL_VALUE_QUIC_IDLE_TIMEOUT: + return qc_getset_idle_timeout(&ctx, class_, NULL, &value); + + case SSL_VALUE_EVENT_HANDLING_MODE: + return qc_getset_event_handling(&ctx, class_, NULL, &value); + + default: + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, + SSL_R_UNSUPPORTED_CONFIG_VALUE, NULL); + } + + return 1; +} + /* * SSL_accept_stream * ----------------- @@ -3259,7 +3622,7 @@ size_t ossl_quic_get_accept_stream_queue_len(SSL *s) quic_lock(ctx.qc); - v = ossl_quic_stream_map_get_accept_queue_len(ossl_quic_channel_get_qsm(ctx.qc->ch)); + v = ossl_quic_stream_map_get_total_accept_queue_len(ossl_quic_channel_get_qsm(ctx.qc->ch)); quic_unlock(ctx.qc); return v; @@ -3292,6 +3655,8 @@ int ossl_quic_stream_reset(SSL *ssl, } ok = ossl_quic_stream_map_reset_stream_send_part(qsm, qs, error_code); + if (ok) + ctx.xso->requested_reset = 1; err: quic_unlock(ctx.qc); @@ -3641,6 +4006,150 @@ int ossl_quic_get_shutdown(const SSL *s) return shut; } +/* + * QUIC Polling Support APIs + * ========================= + */ + +/* Do we have the R (read) condition? */ +QUIC_NEEDS_LOCK +static int test_poll_event_r(QUIC_XSO *xso) +{ + int fin = 0; + size_t avail = 0; + + return ossl_quic_stream_has_recv_buffer(xso->stream) + && ossl_quic_rstream_available(xso->stream->rstream, &avail, &fin) + && (avail > 0 || (fin && !xso->retired_fin)); +} + +/* Do we have the ER (exception: read) condition? */ +QUIC_NEEDS_LOCK +static int test_poll_event_er(QUIC_XSO *xso) +{ + return ossl_quic_stream_has_recv(xso->stream) + && ossl_quic_stream_recv_is_reset(xso->stream) + && !xso->retired_fin; +} + +/* Do we have the W (write) condition? */ +QUIC_NEEDS_LOCK +static int test_poll_event_w(QUIC_XSO *xso) +{ + return !xso->conn->shutting_down + && ossl_quic_stream_has_send_buffer(xso->stream) + && ossl_quic_sstream_get_buffer_avail(xso->stream->sstream) + && !ossl_quic_sstream_get_final_size(xso->stream->sstream, NULL) + && quic_mutation_allowed(xso->conn, /*req_active=*/1); +} + +/* Do we have the EW (exception: write) condition? */ +QUIC_NEEDS_LOCK +static int test_poll_event_ew(QUIC_XSO *xso) +{ + return ossl_quic_stream_has_send(xso->stream) + && xso->stream->peer_stop_sending + && !xso->requested_reset + && !xso->conn->shutting_down; +} + +/* Do we have the EC (exception: connection) condition? */ +QUIC_NEEDS_LOCK +static int test_poll_event_ec(QUIC_CONNECTION *qc) +{ + return ossl_quic_channel_is_term_any(qc->ch); +} + +/* Do we have the ECD (exception: connection drained) condition? */ +QUIC_NEEDS_LOCK +static int test_poll_event_ecd(QUIC_CONNECTION *qc) +{ + return ossl_quic_channel_is_terminated(qc->ch); +} + +/* Do we have the IS (incoming: stream) condition? */ +QUIC_NEEDS_LOCK +static int test_poll_event_is(QUIC_CONNECTION *qc, int is_uni) +{ + return ossl_quic_stream_map_get_accept_queue_len(ossl_quic_channel_get_qsm(qc->ch), + is_uni); +} + +/* Do we have the OS (outgoing: stream) condition? */ +QUIC_NEEDS_LOCK +static int test_poll_event_os(QUIC_CONNECTION *qc, int is_uni) +{ + /* Is it currently possible for us to make an outgoing stream? */ + return quic_mutation_allowed(qc, /*req_active=*/1) + && ossl_quic_channel_get_local_stream_count_avail(qc->ch, is_uni) > 0; +} + +QUIC_TAKES_LOCK +int ossl_quic_conn_poll_events(SSL *ssl, uint64_t events, int do_tick, + uint64_t *p_revents) +{ + QCTX ctx; + uint64_t revents = 0; + + if (!expect_quic(ssl, &ctx)) + return 0; + + quic_lock(ctx.qc); + + if (do_tick) + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + + if (ctx.xso != NULL) { + /* SSL object has a stream component. */ + + if ((events & SSL_POLL_EVENT_R) != 0 + && test_poll_event_r(ctx.xso)) + revents |= SSL_POLL_EVENT_R; + + if ((events & SSL_POLL_EVENT_ER) != 0 + && test_poll_event_er(ctx.xso)) + revents |= SSL_POLL_EVENT_ER; + + if ((events & SSL_POLL_EVENT_W) != 0 + && test_poll_event_w(ctx.xso)) + revents |= SSL_POLL_EVENT_W; + + if ((events & SSL_POLL_EVENT_EW) != 0 + && test_poll_event_ew(ctx.xso)) + revents |= SSL_POLL_EVENT_EW; + } + + if (!ctx.is_stream) { + if ((events & SSL_POLL_EVENT_EC) != 0 + && test_poll_event_ec(ctx.qc)) + revents |= SSL_POLL_EVENT_EC; + + if ((events & SSL_POLL_EVENT_ECD) != 0 + && test_poll_event_ecd(ctx.qc)) + revents |= SSL_POLL_EVENT_ECD; + + if ((events & SSL_POLL_EVENT_ISB) != 0 + && test_poll_event_is(ctx.qc, /*uni=*/0)) + revents |= SSL_POLL_EVENT_ISB; + + if ((events & SSL_POLL_EVENT_ISU) != 0 + && test_poll_event_is(ctx.qc, /*uni=*/1)) + revents |= SSL_POLL_EVENT_ISU; + + if ((events & SSL_POLL_EVENT_OSB) != 0 + && test_poll_event_os(ctx.qc, /*uni=*/0)) + revents |= SSL_POLL_EVENT_OSB; + + if ((events & SSL_POLL_EVENT_OSU) != 0 + && test_poll_event_os(ctx.qc, /*uni=*/1)) + revents |= SSL_POLL_EVENT_OSU; + } + + quic_unlock(ctx.qc); + *p_revents = revents; + return 1; +} + /* * Internal Testing APIs * ===================== @@ -3655,3 +4164,19 @@ QUIC_CHANNEL *ossl_quic_conn_get_channel(SSL *s) return ctx.qc->ch; } + +int ossl_quic_set_diag_title(SSL_CTX *ctx, const char *title) +{ +#ifndef OPENSSL_NO_QLOG + OPENSSL_free(ctx->qlog_title); + ctx->qlog_title = NULL; + + if (title == NULL) + return 1; + + if ((ctx->qlog_title = OPENSSL_strdup(title)) == NULL) + return 0; +#endif + + return 1; +} diff --git a/libs/openssl-3/ssl/quic/quic_lcidm.c b/libs/openssl-3/ssl/quic/quic_lcidm.c new file mode 100644 index 000000000..e5948b95e --- /dev/null +++ b/libs/openssl-3/ssl/quic/quic_lcidm.c @@ -0,0 +1,556 @@ +/* + * 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 + */ + +#include "internal/quic_lcidm.h" +#include "internal/quic_types.h" +#include "internal/quic_vlint.h" +#include "internal/common.h" +#include +#include +#include + +/* + * QUIC Local Connection ID Manager + * ================================ + */ + +typedef struct quic_lcidm_conn_st QUIC_LCIDM_CONN; + +enum { + LCID_TYPE_ODCID, /* This LCID is the ODCID from the peer */ + LCID_TYPE_INITIAL, /* This is our Initial SCID */ + LCID_TYPE_NCID /* This LCID was issued via a NCID frame */ +}; + +typedef struct quic_lcid_st { + QUIC_CONN_ID cid; + uint64_t seq_num; + + /* Back-pointer to the owning QUIC_LCIDM_CONN structure. */ + QUIC_LCIDM_CONN *conn; + + /* LCID_TYPE_* */ + unsigned int type : 2; +} QUIC_LCID; + +DEFINE_LHASH_OF_EX(QUIC_LCID); +DEFINE_LHASH_OF_EX(QUIC_LCIDM_CONN); + +struct quic_lcidm_conn_st { + size_t num_active_lcid; + LHASH_OF(QUIC_LCID) *lcids; + void *opaque; + QUIC_LCID *odcid_lcid_obj; + uint64_t next_seq_num; + + /* Have we enrolled an ODCID? */ + unsigned int done_odcid : 1; +}; + +struct quic_lcidm_st { + OSSL_LIB_CTX *libctx; + LHASH_OF(QUIC_LCID) *lcids; /* (QUIC_CONN_ID) -> (QUIC_LCID *) */ + LHASH_OF(QUIC_LCIDM_CONN) *conns; /* (void *opaque) -> (QUIC_LCIDM_CONN *) */ + size_t lcid_len; /* Length in bytes for all LCIDs */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + QUIC_CONN_ID next_lcid; +#endif +}; + +static unsigned long bin_hash(const unsigned char *buf, size_t buf_len) +{ + unsigned long hash = 0; + size_t i; + + for (i = 0; i < buf_len; ++i) + hash ^= ((unsigned long)buf[i]) << (8 * (i % sizeof(unsigned long))); + + return hash; +} + +static unsigned long lcid_hash(const QUIC_LCID *lcid_obj) +{ + return bin_hash(lcid_obj->cid.id, lcid_obj->cid.id_len); +} + +static int lcid_comp(const QUIC_LCID *a, const QUIC_LCID *b) +{ + return !ossl_quic_conn_id_eq(&a->cid, &b->cid); +} + +static unsigned long lcidm_conn_hash(const QUIC_LCIDM_CONN *conn) +{ + return (unsigned long)(uintptr_t)conn->opaque; +} + +static int lcidm_conn_comp(const QUIC_LCIDM_CONN *a, const QUIC_LCIDM_CONN *b) +{ + return a->opaque != b->opaque; +} + +QUIC_LCIDM *ossl_quic_lcidm_new(OSSL_LIB_CTX *libctx, size_t lcid_len) +{ + QUIC_LCIDM *lcidm = NULL; + + if (lcid_len > QUIC_MAX_CONN_ID_LEN) + goto err; + + if ((lcidm = OPENSSL_zalloc(sizeof(*lcidm))) == NULL) + goto err; + + if ((lcidm->lcids = lh_QUIC_LCID_new(lcid_hash, lcid_comp)) == NULL) + goto err; + + if ((lcidm->conns = lh_QUIC_LCIDM_CONN_new(lcidm_conn_hash, + lcidm_conn_comp)) == NULL) + goto err; + + lcidm->libctx = libctx; + lcidm->lcid_len = lcid_len; + return lcidm; + +err: + if (lcidm != NULL) { + lh_QUIC_LCID_free(lcidm->lcids); + lh_QUIC_LCIDM_CONN_free(lcidm->conns); + OPENSSL_free(lcidm); + } + return NULL; +} + +static void lcidm_delete_conn(QUIC_LCIDM *lcidm, QUIC_LCIDM_CONN *conn); + +static void lcidm_delete_conn_(QUIC_LCIDM_CONN *conn, void *arg) +{ + lcidm_delete_conn((QUIC_LCIDM *)arg, conn); +} + +void ossl_quic_lcidm_free(QUIC_LCIDM *lcidm) +{ + if (lcidm == NULL) + return; + + /* + * Calling OPENSSL_lh_delete during a doall call is unsafe with our + * current LHASH implementation for several reasons: + * + * - firstly, because deletes can cause the hashtable to be contracted, + * resulting in rehashing which might cause items in later buckets to + * move to earlier buckets, which might cause doall to skip an item, + * resulting in a memory leak; + * + * - secondly, because doall in general is not safe across hashtable + * size changes, as it caches hashtable size and pointer values + * while operating. + * + * The fix for this is to disable hashtable contraction using the following + * call, which guarantees that no rehashing will occur so long as we only + * call delete and not insert. + */ + lh_QUIC_LCIDM_CONN_set_down_load(lcidm->conns, 0); + + lh_QUIC_LCIDM_CONN_doall_arg(lcidm->conns, lcidm_delete_conn_, lcidm); + + lh_QUIC_LCID_free(lcidm->lcids); + lh_QUIC_LCIDM_CONN_free(lcidm->conns); + OPENSSL_free(lcidm); +} + +static QUIC_LCID *lcidm_get0_lcid(const QUIC_LCIDM *lcidm, const QUIC_CONN_ID *lcid) +{ + QUIC_LCID key; + + key.cid = *lcid; + + if (key.cid.id_len > QUIC_MAX_CONN_ID_LEN) + return NULL; + + return lh_QUIC_LCID_retrieve(lcidm->lcids, &key); +} + +static QUIC_LCIDM_CONN *lcidm_get0_conn(const QUIC_LCIDM *lcidm, void *opaque) +{ + QUIC_LCIDM_CONN key; + + key.opaque = opaque; + + return lh_QUIC_LCIDM_CONN_retrieve(lcidm->conns, &key); +} + +static QUIC_LCIDM_CONN *lcidm_upsert_conn(const QUIC_LCIDM *lcidm, void *opaque) +{ + QUIC_LCIDM_CONN *conn = lcidm_get0_conn(lcidm, opaque); + + if (conn != NULL) + return conn; + + if ((conn = OPENSSL_zalloc(sizeof(*conn))) == NULL) + goto err; + + if ((conn->lcids = lh_QUIC_LCID_new(lcid_hash, lcid_comp)) == NULL) + goto err; + + conn->opaque = opaque; + + lh_QUIC_LCIDM_CONN_insert(lcidm->conns, conn); + if (lh_QUIC_LCIDM_CONN_error(lcidm->conns)) + goto err; + + return conn; + +err: + if (conn != NULL) { + lh_QUIC_LCID_free(conn->lcids); + OPENSSL_free(conn); + } + return NULL; +} + +static void lcidm_delete_conn_lcid(QUIC_LCIDM *lcidm, QUIC_LCID *lcid_obj) +{ + lh_QUIC_LCID_delete(lcidm->lcids, lcid_obj); + lh_QUIC_LCID_delete(lcid_obj->conn->lcids, lcid_obj); + assert(lcid_obj->conn->num_active_lcid > 0); + --lcid_obj->conn->num_active_lcid; + OPENSSL_free(lcid_obj); +} + +/* doall_arg wrapper */ +static void lcidm_delete_conn_lcid_(QUIC_LCID *lcid_obj, void *arg) +{ + lcidm_delete_conn_lcid((QUIC_LCIDM *)arg, lcid_obj); +} + +static void lcidm_delete_conn(QUIC_LCIDM *lcidm, QUIC_LCIDM_CONN *conn) +{ + /* See comment in ossl_quic_lcidm_free */ + lh_QUIC_LCID_set_down_load(conn->lcids, 0); + + lh_QUIC_LCID_doall_arg(conn->lcids, lcidm_delete_conn_lcid_, lcidm); + lh_QUIC_LCIDM_CONN_delete(lcidm->conns, conn); + lh_QUIC_LCID_free(conn->lcids); + OPENSSL_free(conn); +} + +static QUIC_LCID *lcidm_conn_new_lcid(QUIC_LCIDM *lcidm, QUIC_LCIDM_CONN *conn, + const QUIC_CONN_ID *lcid) +{ + QUIC_LCID *lcid_obj = NULL; + + if (lcid->id_len > QUIC_MAX_CONN_ID_LEN) + return NULL; + + if ((lcid_obj = OPENSSL_zalloc(sizeof(*lcid_obj))) == NULL) + goto err; + + lcid_obj->cid = *lcid; + lcid_obj->conn = conn; + + lh_QUIC_LCID_insert(conn->lcids, lcid_obj); + if (lh_QUIC_LCID_error(conn->lcids)) + goto err; + + lh_QUIC_LCID_insert(lcidm->lcids, lcid_obj); + if (lh_QUIC_LCID_error(lcidm->lcids)) { + lh_QUIC_LCID_delete(conn->lcids, lcid_obj); + goto err; + } + + ++conn->num_active_lcid; + return lcid_obj; + +err: + OPENSSL_free(lcid_obj); + return NULL; +} + +size_t ossl_quic_lcidm_get_lcid_len(const QUIC_LCIDM *lcidm) +{ + return lcidm->lcid_len; +} + +size_t ossl_quic_lcidm_get_num_active_lcid(const QUIC_LCIDM *lcidm, + void *opaque) +{ + QUIC_LCIDM_CONN *conn; + + conn = lcidm_get0_conn(lcidm, opaque); + if (conn == NULL) + return 0; + + return conn->num_active_lcid; +} + +static int lcidm_generate_cid(QUIC_LCIDM *lcidm, + QUIC_CONN_ID *cid) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + int i; + + lcidm->next_lcid.id_len = (unsigned char)lcidm->lcid_len; + *cid = lcidm->next_lcid; + + for (i = lcidm->lcid_len - 1; i >= 0; --i) + if (++lcidm->next_lcid.id[i] != 0) + break; + + return 1; +#else + return ossl_quic_gen_rand_conn_id(lcidm->libctx, lcidm->lcid_len, cid); +#endif +} + +static int lcidm_generate(QUIC_LCIDM *lcidm, + void *opaque, + unsigned int type, + QUIC_CONN_ID *lcid_out, + uint64_t *seq_num) +{ + QUIC_LCIDM_CONN *conn; + QUIC_LCID key, *lcid_obj; + size_t i; +#define MAX_RETRIES 8 + + if ((conn = lcidm_upsert_conn(lcidm, opaque)) == NULL) + return 0; + + if ((type == LCID_TYPE_INITIAL && conn->next_seq_num > 0) + || conn->next_seq_num > OSSL_QUIC_VLINT_MAX) + return 0; + + i = 0; + do { + if (i++ >= MAX_RETRIES) + /* + * Too many retries; should not happen but if it does, don't loop + * endlessly. + */ + return 0; + + if (!lcidm_generate_cid(lcidm, lcid_out)) + return 0; + + key.cid = *lcid_out; + /* If a collision occurs, retry. */ + } while (lh_QUIC_LCID_retrieve(lcidm->lcids, &key) != NULL); + + if ((lcid_obj = lcidm_conn_new_lcid(lcidm, conn, lcid_out)) == NULL) + return 0; + + lcid_obj->seq_num = conn->next_seq_num; + lcid_obj->type = type; + + if (seq_num != NULL) + *seq_num = lcid_obj->seq_num; + + ++conn->next_seq_num; + return 1; +} + +int ossl_quic_lcidm_enrol_odcid(QUIC_LCIDM *lcidm, + void *opaque, + const QUIC_CONN_ID *initial_odcid) +{ + QUIC_LCIDM_CONN *conn; + QUIC_LCID key, *lcid_obj; + + if (initial_odcid == NULL || initial_odcid->id_len < QUIC_MIN_ODCID_LEN + || initial_odcid->id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + if ((conn = lcidm_upsert_conn(lcidm, opaque)) == NULL) + return 0; + + if (conn->done_odcid) + return 0; + + key.cid = *initial_odcid; + if (lh_QUIC_LCID_retrieve(lcidm->lcids, &key) != NULL) + return 0; + + if ((lcid_obj = lcidm_conn_new_lcid(lcidm, conn, initial_odcid)) == NULL) + return 0; + + lcid_obj->seq_num = LCIDM_ODCID_SEQ_NUM; + lcid_obj->type = LCID_TYPE_ODCID; + + conn->odcid_lcid_obj = lcid_obj; + conn->done_odcid = 1; + return 1; +} + +int ossl_quic_lcidm_generate_initial(QUIC_LCIDM *lcidm, + void *opaque, + QUIC_CONN_ID *initial_lcid) +{ + return lcidm_generate(lcidm, opaque, LCID_TYPE_INITIAL, + initial_lcid, NULL); +} + +int ossl_quic_lcidm_generate(QUIC_LCIDM *lcidm, + void *opaque, + OSSL_QUIC_FRAME_NEW_CONN_ID *ncid_frame) +{ + ncid_frame->seq_num = 0; + ncid_frame->retire_prior_to = 0; + + return lcidm_generate(lcidm, opaque, LCID_TYPE_NCID, + &ncid_frame->conn_id, + &ncid_frame->seq_num); +} + +int ossl_quic_lcidm_retire_odcid(QUIC_LCIDM *lcidm, void *opaque) +{ + QUIC_LCIDM_CONN *conn; + + if ((conn = lcidm_upsert_conn(lcidm, opaque)) == NULL) + return 0; + + if (conn->odcid_lcid_obj == NULL) + return 0; + + lcidm_delete_conn_lcid(lcidm, conn->odcid_lcid_obj); + conn->odcid_lcid_obj = NULL; + return 1; +} + +struct retire_args { + QUIC_LCID *earliest_seq_num_lcid_obj; + uint64_t earliest_seq_num, retire_prior_to; +}; + +static void retire_for_conn(QUIC_LCID *lcid_obj, void *arg) +{ + struct retire_args *args = arg; + + /* ODCID LCID cannot be retired via this API */ + if (lcid_obj->type == LCID_TYPE_ODCID + || lcid_obj->seq_num >= args->retire_prior_to) + return; + + if (lcid_obj->seq_num < args->earliest_seq_num) { + args->earliest_seq_num = lcid_obj->seq_num; + args->earliest_seq_num_lcid_obj = lcid_obj; + } +} + +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) +{ + QUIC_LCIDM_CONN key, *conn; + struct retire_args args = {0}; + + key.opaque = opaque; + + if (did_retire == NULL) + return 0; + + *did_retire = 0; + if ((conn = lh_QUIC_LCIDM_CONN_retrieve(lcidm->conns, &key)) == NULL) + return 1; + + args.retire_prior_to = retire_prior_to; + args.earliest_seq_num = UINT64_MAX; + + lh_QUIC_LCID_doall_arg(conn->lcids, retire_for_conn, &args); + if (args.earliest_seq_num_lcid_obj == NULL) + return 1; + + if (containing_pkt_dcid != NULL + && ossl_quic_conn_id_eq(&args.earliest_seq_num_lcid_obj->cid, + containing_pkt_dcid)) + return 0; + + *did_retire = 1; + if (retired_lcid != NULL) + *retired_lcid = args.earliest_seq_num_lcid_obj->cid; + if (retired_seq_num != NULL) + *retired_seq_num = args.earliest_seq_num_lcid_obj->seq_num; + + lcidm_delete_conn_lcid(lcidm, args.earliest_seq_num_lcid_obj); + return 1; +} + +int ossl_quic_lcidm_cull(QUIC_LCIDM *lcidm, void *opaque) +{ + QUIC_LCIDM_CONN key, *conn; + + key.opaque = opaque; + + if ((conn = lh_QUIC_LCIDM_CONN_retrieve(lcidm->conns, &key)) == NULL) + return 0; + + lcidm_delete_conn(lcidm, conn); + return 1; +} + +int ossl_quic_lcidm_lookup(QUIC_LCIDM *lcidm, + const QUIC_CONN_ID *lcid, + uint64_t *seq_num, + void **opaque) +{ + QUIC_LCID *lcid_obj; + + if (lcid == NULL) + return 0; + + if ((lcid_obj = lcidm_get0_lcid(lcidm, lcid)) == NULL) + return 0; + + if (seq_num != NULL) + *seq_num = lcid_obj->seq_num; + + if (opaque != NULL) + *opaque = lcid_obj->conn->opaque; + + return 1; +} + +int ossl_quic_lcidm_debug_remove(QUIC_LCIDM *lcidm, + const QUIC_CONN_ID *lcid) +{ + QUIC_LCID key, *lcid_obj; + + key.cid = *lcid; + if ((lcid_obj = lh_QUIC_LCID_retrieve(lcidm->lcids, &key)) == NULL) + return 0; + + lcidm_delete_conn_lcid(lcidm, lcid_obj); + return 1; +} + +int ossl_quic_lcidm_debug_add(QUIC_LCIDM *lcidm, void *opaque, + const QUIC_CONN_ID *lcid, + uint64_t seq_num) +{ + QUIC_LCIDM_CONN *conn; + QUIC_LCID key, *lcid_obj; + + if (lcid == NULL || lcid->id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + if ((conn = lcidm_upsert_conn(lcidm, opaque)) == NULL) + return 0; + + key.cid = *lcid; + if (lh_QUIC_LCID_retrieve(lcidm->lcids, &key) != NULL) + return 0; + + if ((lcid_obj = lcidm_conn_new_lcid(lcidm, conn, lcid)) == NULL) + return 0; + + lcid_obj->seq_num = seq_num; + lcid_obj->type = LCID_TYPE_NCID; + return 1; +} diff --git a/libs/openssl-3/ssl/quic/quic_local.h b/libs/openssl-3/ssl/quic/quic_local.h index 928ae4c6b..d6518fd6b 100644 --- a/libs/openssl-3/ssl/quic/quic_local.h +++ b/libs/openssl-3/ssl/quic/quic_local.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 @@ -54,6 +54,15 @@ struct quic_xso_st { */ unsigned int desires_blocking_set : 1; + /* The application has retired a FIN (i.e. SSL_ERROR_ZERO_RETURN). */ + unsigned int retired_fin : 1; + + /* + * The application has requested a reset. Not set for reflexive + * STREAM_RESETs caused by peer STOP_SENDING. + */ + unsigned int requested_reset : 1; + /* * This state tracks SSL_write all-or-nothing (AON) write semantics * emulation. @@ -74,6 +83,10 @@ struct quic_xso_st { */ /* Is an AON write in progress? */ unsigned int aon_write_in_progress : 1; + + /* Event handling mode. One of SSL_QUIC_VALUE_EVENT_HANDLING. */ + unsigned int event_handling_mode : 2; + /* * The base buffer pointer the caller passed us for the initial AON write * call. We use this for validation purposes unless @@ -118,6 +131,12 @@ struct quic_conn_st { SSL *tls; + /* The QUIC engine representing the QUIC event domain. */ + QUIC_ENGINE *engine; + + /* The QUIC port representing the QUIC listener and socket. */ + QUIC_PORT *port; + /* * The QUIC channel providing the core QUIC connection implementation. Note * that this is not instantiated until we actually start trying to do the @@ -202,6 +221,9 @@ struct quic_conn_st { unsigned int addressed_mode_w : 1; unsigned int addressed_mode_r : 1; + /* Event handling mode. One of SSL_QUIC_VALUE_EVENT_HANDLING. */ + unsigned int event_handling_mode : 2; + /* Default stream type. Defaults to SSL_DEFAULT_STREAM_MODE_AUTO_BIDI. */ uint32_t default_stream_mode; @@ -228,8 +250,9 @@ int ossl_quic_conn_on_handshake_confirmed(QUIC_CONNECTION *qc); /* * To be called when a protocol violation occurs. The connection is torn down - * with the given error code, which should be a QUIC_ERR_* value. Reason string - * is optional and copied if provided. frame_type should be 0 if not applicable. + * with the given error code, which should be a OSSL_QUIC_ERR_* value. Reason + * string is optional and copied if provided. frame_type should be 0 if not + * applicable. */ void ossl_quic_conn_raise_protocol_error(QUIC_CONNECTION *qc, uint64_t error_code, diff --git a/libs/openssl-3/ssl/quic/quic_port.c b/libs/openssl-3/ssl/quic/quic_port.c new file mode 100644 index 000000000..96c289f7e --- /dev/null +++ b/libs/openssl-3/ssl/quic/quic_port.c @@ -0,0 +1,615 @@ +/* + * 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 + */ + +#include "internal/quic_port.h" +#include "internal/quic_channel.h" +#include "internal/quic_lcidm.h" +#include "internal/quic_srtm.h" +#include "quic_port_local.h" +#include "quic_channel_local.h" +#include "quic_engine_local.h" +#include "../ssl_local.h" + +/* + * QUIC Port Structure + * =================== + */ +#define INIT_DCID_LEN 8 + +static int port_init(QUIC_PORT *port); +static void port_cleanup(QUIC_PORT *port); +static OSSL_TIME get_time(void *arg); +static void port_default_packet_handler(QUIC_URXE *e, void *arg, + const QUIC_CONN_ID *dcid); +static void port_rx_pre(QUIC_PORT *port); + +DEFINE_LIST_OF_IMPL(ch, QUIC_CHANNEL); +DEFINE_LIST_OF_IMPL(port, QUIC_PORT); + +QUIC_PORT *ossl_quic_port_new(const QUIC_PORT_ARGS *args) +{ + QUIC_PORT *port; + + if ((port = OPENSSL_zalloc(sizeof(QUIC_PORT))) == NULL) + return NULL; + + port->engine = args->engine; + port->channel_ctx = args->channel_ctx; + port->is_multi_conn = args->is_multi_conn; + + if (!port_init(port)) { + OPENSSL_free(port); + return NULL; + } + + return port; +} + +void ossl_quic_port_free(QUIC_PORT *port) +{ + if (port == NULL) + return; + + port_cleanup(port); + OPENSSL_free(port); +} + +static int port_init(QUIC_PORT *port) +{ + size_t rx_short_dcid_len = (port->is_multi_conn ? INIT_DCID_LEN : 0); + + if (port->engine == NULL || port->channel_ctx == NULL) + goto err; + + if ((port->err_state = OSSL_ERR_STATE_new()) == NULL) + goto err; + + if ((port->demux = ossl_quic_demux_new(/*BIO=*/NULL, + /*Short CID Len=*/rx_short_dcid_len, + get_time, port)) == NULL) + goto err; + + ossl_quic_demux_set_default_handler(port->demux, + port_default_packet_handler, + port); + + if ((port->srtm = ossl_quic_srtm_new(port->engine->libctx, + port->engine->propq)) == NULL) + goto err; + + if ((port->lcidm = ossl_quic_lcidm_new(port->engine->libctx, + rx_short_dcid_len)) == NULL) + goto err; + + port->rx_short_dcid_len = (unsigned char)rx_short_dcid_len; + port->tx_init_dcid_len = INIT_DCID_LEN; + port->state = QUIC_PORT_STATE_RUNNING; + + ossl_list_port_insert_tail(&port->engine->port_list, port); + port->on_engine_list = 1; + return 1; + +err: + port_cleanup(port); + return 0; +} + +static void port_cleanup(QUIC_PORT *port) +{ + assert(ossl_list_ch_num(&port->channel_list) == 0); + + ossl_quic_demux_free(port->demux); + port->demux = NULL; + + ossl_quic_srtm_free(port->srtm); + port->srtm = NULL; + + ossl_quic_lcidm_free(port->lcidm); + port->lcidm = NULL; + + OSSL_ERR_STATE_free(port->err_state); + port->err_state = NULL; + + if (port->on_engine_list) { + ossl_list_port_remove(&port->engine->port_list, port); + port->on_engine_list = 0; + } +} + +static void port_transition_failed(QUIC_PORT *port) +{ + if (port->state == QUIC_PORT_STATE_FAILED) + return; + + port->state = QUIC_PORT_STATE_FAILED; +} + +int ossl_quic_port_is_running(const QUIC_PORT *port) +{ + return port->state == QUIC_PORT_STATE_RUNNING; +} + +QUIC_ENGINE *ossl_quic_port_get0_engine(QUIC_PORT *port) +{ + return port->engine; +} + +QUIC_REACTOR *ossl_quic_port_get0_reactor(QUIC_PORT *port) +{ + return ossl_quic_engine_get0_reactor(port->engine); +} + +QUIC_DEMUX *ossl_quic_port_get0_demux(QUIC_PORT *port) +{ + return port->demux; +} + +CRYPTO_MUTEX *ossl_quic_port_get0_mutex(QUIC_PORT *port) +{ + return ossl_quic_engine_get0_mutex(port->engine); +} + +OSSL_TIME ossl_quic_port_get_time(QUIC_PORT *port) +{ + return ossl_quic_engine_get_time(port->engine); +} + +static OSSL_TIME get_time(void *port) +{ + return ossl_quic_port_get_time((QUIC_PORT *)port); +} + +int ossl_quic_port_get_rx_short_dcid_len(const QUIC_PORT *port) +{ + return port->rx_short_dcid_len; +} + +int ossl_quic_port_get_tx_init_dcid_len(const QUIC_PORT *port) +{ + return port->tx_init_dcid_len; +} + +/* + * QUIC Port: Network BIO Configuration + * ==================================== + */ + +/* Determines whether we can support a given poll descriptor. */ +static int validate_poll_descriptor(const BIO_POLL_DESCRIPTOR *d) +{ + if (d->type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD && d->value.fd < 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + return 1; +} + +BIO *ossl_quic_port_get_net_rbio(QUIC_PORT *port) +{ + return port->net_rbio; +} + +BIO *ossl_quic_port_get_net_wbio(QUIC_PORT *port) +{ + return port->net_wbio; +} + +static int port_update_poll_desc(QUIC_PORT *port, BIO *net_bio, int for_write) +{ + BIO_POLL_DESCRIPTOR d = {0}; + + if (net_bio == NULL + || (!for_write && !BIO_get_rpoll_descriptor(net_bio, &d)) + || (for_write && !BIO_get_wpoll_descriptor(net_bio, &d))) + /* Non-pollable BIO */ + d.type = BIO_POLL_DESCRIPTOR_TYPE_NONE; + + if (!validate_poll_descriptor(&d)) + return 0; + + /* + * TODO(QUIC MULTIPORT): We currently only support one port per + * engine/domain. This is necessitated because QUIC_REACTOR only supports a + * single pollable currently. In the future, once complete polling + * infrastructure has been implemented, this limitation can be removed. + * + * For now, just update the descriptor on the the engine's reactor as we are + * guaranteed to be the only port under it. + */ + if (for_write) + ossl_quic_reactor_set_poll_w(&port->engine->rtor, &d); + else + ossl_quic_reactor_set_poll_r(&port->engine->rtor, &d); + + return 1; +} + +int ossl_quic_port_update_poll_descriptors(QUIC_PORT *port) +{ + int ok = 1; + + if (!port_update_poll_desc(port, port->net_rbio, /*for_write=*/0)) + ok = 0; + + if (!port_update_poll_desc(port, port->net_wbio, /*for_write=*/1)) + ok = 0; + + return ok; +} + +/* + * QUIC_PORT does not ref any BIO it is provided with, nor is any ref + * transferred to it. The caller (e.g., QUIC_CONNECTION) is responsible for + * ensuring the BIO lasts until the channel is freed or the BIO is switched out + * for another BIO by a subsequent successful call to this function. + */ +int ossl_quic_port_set_net_rbio(QUIC_PORT *port, BIO *net_rbio) +{ + if (port->net_rbio == net_rbio) + return 1; + + if (!port_update_poll_desc(port, net_rbio, /*for_write=*/0)) + return 0; + + ossl_quic_demux_set_bio(port->demux, net_rbio); + port->net_rbio = net_rbio; + return 1; +} + +int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio) +{ + QUIC_CHANNEL *ch; + + if (port->net_wbio == net_wbio) + return 1; + + if (!port_update_poll_desc(port, net_wbio, /*for_write=*/1)) + return 0; + + LIST_FOREACH(ch, ch, &port->channel_list) + ossl_qtx_set_bio(ch->qtx, net_wbio); + + port->net_wbio = net_wbio; + return 1; +} + +/* + * QUIC Port: Channel Lifecycle + * ============================ + */ + +static SSL *port_new_handshake_layer(QUIC_PORT *port) +{ + SSL *tls = NULL; + SSL_CONNECTION *tls_conn = NULL; + + tls = ossl_ssl_connection_new_int(port->channel_ctx, TLS_method()); + if (tls == NULL || (tls_conn = SSL_CONNECTION_FROM_SSL(tls)) == NULL) + return NULL; + + /* Override the user_ssl of the inner connection. */ + tls_conn->s3.flags |= TLS1_FLAGS_QUIC; + + /* Restrict options derived from the SSL_CTX. */ + tls_conn->options &= OSSL_QUIC_PERMITTED_OPTIONS_CONN; + tls_conn->pha_enabled = 0; + return tls; +} + +static QUIC_CHANNEL *port_make_channel(QUIC_PORT *port, SSL *tls, int is_server) +{ + QUIC_CHANNEL_ARGS args = {0}; + QUIC_CHANNEL *ch; + + args.port = port; + args.is_server = is_server; + args.tls = (tls != NULL ? tls : port_new_handshake_layer(port)); + args.lcidm = port->lcidm; + args.srtm = port->srtm; + if (args.tls == NULL) + return NULL; + +#ifndef OPENSSL_NO_QLOG + args.use_qlog = 1; /* disabled if env not set */ + args.qlog_title = args.tls->ctx->qlog_title; +#endif + + ch = ossl_quic_channel_new(&args); + if (ch == NULL) { + if (tls == NULL) + SSL_free(args.tls); + + return NULL; + } + + return ch; +} + +QUIC_CHANNEL *ossl_quic_port_create_outgoing(QUIC_PORT *port, SSL *tls) +{ + return port_make_channel(port, tls, /*is_server=*/0); +} + +QUIC_CHANNEL *ossl_quic_port_create_incoming(QUIC_PORT *port, SSL *tls) +{ + QUIC_CHANNEL *ch; + + assert(port->tserver_ch == NULL); + + ch = port_make_channel(port, tls, /*is_server=*/1); + port->tserver_ch = ch; + port->is_server = 1; + return ch; +} + +/* + * QUIC Port: Ticker-Mutator + * ========================= + */ + +/* + * Tick function for this port. This does everything related to network I/O for + * this port's network BIOs, and services child channels. + */ +void ossl_quic_port_subtick(QUIC_PORT *port, QUIC_TICK_RESULT *res, + uint32_t flags) +{ + QUIC_CHANNEL *ch; + + res->net_read_desired = 0; + res->net_write_desired = 0; + res->tick_deadline = ossl_time_infinite(); + + if (!port->engine->inhibit_tick) { + /* Handle any incoming data from network. */ + if (ossl_quic_port_is_running(port)) + port_rx_pre(port); + + /* Iterate through all channels and service them. */ + LIST_FOREACH(ch, ch, &port->channel_list) { + QUIC_TICK_RESULT subr = {0}; + + ossl_quic_channel_subtick(ch, &subr, flags); + ossl_quic_tick_result_merge_into(res, &subr); + } + } +} + +/* Process incoming datagrams, if any. */ +static void port_rx_pre(QUIC_PORT *port) +{ + int ret; + + /* + * Originally, this check (don't RX before we have sent anything if we are + * not a server, because there can't be anything) was just intended as a + * minor optimisation. However, it is actually required on Windows, and + * removing this check will cause Windows to break. + * + * The reason is that under Win32, recvfrom() does not work on a UDP socket + * which has not had bind() called (???). However, calling sendto() will + * automatically bind an unbound UDP socket. Therefore, if we call a Winsock + * recv-type function before calling a Winsock send-type function, that call + * will fail with WSAEINVAL, which we will regard as a permanent network + * error. + * + * Therefore, this check is essential as we do not require our API users to + * bind a socket first when using the API in client mode. + */ + if (!port->is_server && !port->have_sent_any_pkt) + return; + + /* + * Get DEMUX to BIO_recvmmsg from the network and queue incoming datagrams + * to the appropriate QRX instances. + */ + ret = ossl_quic_demux_pump(port->demux); + if (ret == QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL) + /* + * We don't care about transient failure, but permanent failure means we + * should tear down the port. All connections skip straight to the + * Terminated state as there is no point trying to send CONNECTION_CLOSE + * frames if the network BIO is not operating correctly. + */ + ossl_quic_port_raise_net_error(port, NULL); +} + +/* + * Handles an incoming connection request and potentially decides to make a + * connection from it. If a new connection is made, the new channel is written + * to *new_ch. + */ +static void port_on_new_conn(QUIC_PORT *port, const BIO_ADDR *peer, + const QUIC_CONN_ID *scid, + const QUIC_CONN_ID *dcid, + QUIC_CHANNEL **new_ch) +{ + if (port->tserver_ch != NULL) { + /* Specially assign to existing channel */ + if (!ossl_quic_channel_on_new_conn(port->tserver_ch, peer, scid, dcid)) + return; + + *new_ch = port->tserver_ch; + port->tserver_ch = NULL; + return; + } +} + +static int port_try_handle_stateless_reset(QUIC_PORT *port, const QUIC_URXE *e) +{ + size_t i; + const unsigned char *data = ossl_quic_urxe_data(e); + void *opaque = NULL; + + /* + * Perform some fast and cheap checks for a packet not being a stateless + * reset token. RFC 9000 s. 10.3 specifies this layout for stateless + * reset packets: + * + * Stateless Reset { + * Fixed Bits (2) = 1, + * Unpredictable Bits (38..), + * Stateless Reset Token (128), + * } + * + * It also specifies: + * However, endpoints MUST treat any packet ending in a valid + * stateless reset token as a Stateless Reset, as other QUIC + * versions might allow the use of a long header. + * + * We can rapidly check for the minimum length and that the first pair + * of bits in the first byte are 01 or 11. + * + * The function returns 1 if it is a stateless reset packet, 0 if it isn't + * and -1 if an error was encountered. + */ + if (e->data_len < QUIC_STATELESS_RESET_TOKEN_LEN + 5 + || (0100 & *data) != 0100) + return 0; + + for (i = 0;; ++i) { + if (!ossl_quic_srtm_lookup(port->srtm, + (QUIC_STATELESS_RESET_TOKEN *)(data + e->data_len + - sizeof(QUIC_STATELESS_RESET_TOKEN)), + i, &opaque, NULL)) + break; + + assert(opaque != NULL); + ossl_quic_channel_on_stateless_reset((QUIC_CHANNEL *)opaque); + } + + return i > 0; +} + +/* + * This is called by the demux when we get a packet not destined for any known + * DCID. + */ +static void port_default_packet_handler(QUIC_URXE *e, void *arg, + const QUIC_CONN_ID *dcid) +{ + QUIC_PORT *port = arg; + PACKET pkt; + QUIC_PKT_HDR hdr; + QUIC_CHANNEL *ch = NULL, *new_ch = NULL; + + /* Don't handle anything if we are no longer running. */ + if (!ossl_quic_port_is_running(port)) + goto undesirable; + + if (port_try_handle_stateless_reset(port, e)) + goto undesirable; + + if (dcid != NULL + && ossl_quic_lcidm_lookup(port->lcidm, dcid, NULL, + (void **)&ch)) { + assert(ch != NULL); + ossl_quic_channel_inject(ch, e); + return; + } + + /* + * If we have an incoming packet which doesn't match any existing connection + * we assume this is an attempt to make a new connection. Currently we + * require our caller to have precreated a latent 'incoming' channel via + * TSERVER which then gets turned into the new connection. + * + * TODO(QUIC SERVER): In the future we will construct channels dynamically + * in this case. + */ + if (port->tserver_ch == NULL) + goto undesirable; + + /* + * We have got a packet for an unknown DCID. This might be an attempt to + * open a new connection. + */ + if (e->data_len < QUIC_MIN_INITIAL_DGRAM_LEN) + goto undesirable; + + if (!PACKET_buf_init(&pkt, ossl_quic_urxe_data(e), e->data_len)) + goto undesirable; + + /* + * We set short_conn_id_len to SIZE_MAX here which will cause the decode + * operation to fail if we get a 1-RTT packet. This is fine since we only + * care about Initial packets. + */ + if (!ossl_quic_wire_decode_pkt_hdr(&pkt, SIZE_MAX, 1, 0, &hdr, NULL)) + goto undesirable; + + switch (hdr.version) { + case QUIC_VERSION_1: + break; + + case QUIC_VERSION_NONE: + default: + /* Unknown version or proactive version negotiation request, bail. */ + /* TODO(QUIC SERVER): Handle version negotiation on server side */ + goto undesirable; + } + + /* + * We only care about Initial packets which might be trying to establish a + * connection. + */ + if (hdr.type != QUIC_PKT_TYPE_INITIAL) + goto undesirable; + + /* + * Try to process this as a valid attempt to initiate a connection. + * + * The channel will do all the LCID registration needed, but as an + * optimization inject this packet directly into the channel's QRX for + * processing without going through the DEMUX again. + */ + port_on_new_conn(port, &e->peer, &hdr.src_conn_id, &hdr.dst_conn_id, + &new_ch); + if (new_ch != NULL) + ossl_qrx_inject_urxe(new_ch->qrx, e); + + return; + +undesirable: + ossl_quic_demux_release_urxe(port->demux, e); +} + +void ossl_quic_port_raise_net_error(QUIC_PORT *port, + QUIC_CHANNEL *triggering_ch) +{ + QUIC_CHANNEL *ch; + + if (!ossl_quic_port_is_running(port)) + return; + + /* + * Immediately capture any triggering error on the error stack, with a + * cover error. + */ + ERR_raise_data(ERR_LIB_SSL, SSL_R_QUIC_NETWORK_ERROR, + "port failed due to network BIO I/O error"); + OSSL_ERR_STATE_save(port->err_state); + + port_transition_failed(port); + + /* Give the triggering channel (if any) the first notification. */ + if (triggering_ch != NULL) + ossl_quic_channel_raise_net_error(triggering_ch); + + LIST_FOREACH(ch, ch, &port->channel_list) + if (ch != triggering_ch) + ossl_quic_channel_raise_net_error(ch); +} + +void ossl_quic_port_restore_err_state(const QUIC_PORT *port) +{ + ERR_clear_error(); + OSSL_ERR_STATE_restore(port->err_state); +} diff --git a/libs/openssl-3/ssl/quic/quic_port_local.h b/libs/openssl-3/ssl/quic/quic_port_local.h new file mode 100644 index 000000000..b5e120636 --- /dev/null +++ b/libs/openssl-3/ssl/quic/quic_port_local.h @@ -0,0 +1,100 @@ +/* + * 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_LOCAL_H +# define OSSL_QUIC_PORT_LOCAL_H + +# include "internal/quic_port.h" +# include "internal/quic_reactor.h" +# include "internal/list.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Port Structure + * =================== + * + * QUIC port internals. It is intended that only the QUIC_PORT and QUIC_CHANNEL + * implementation be allowed to access this structure directly. + * + * Other components should not include this header. + */ +DECLARE_LIST_OF(ch, QUIC_CHANNEL); + +/* A port is always in one of the following states: */ +enum { + /* Initial and steady state. */ + QUIC_PORT_STATE_RUNNING, + + /* + * Terminal state indicating port is no longer functioning. There are no + * transitions out of this state. May be triggered by e.g. a permanent + * network BIO error. + */ + QUIC_PORT_STATE_FAILED +}; + +struct quic_port_st { + /* The engine which this port is a child of. */ + QUIC_ENGINE *engine; + + /* + * QUIC_ENGINE keeps the ports which belong to it on a list for bookkeeping + * purposes. + */ + OSSL_LIST_MEMBER(port, QUIC_PORT); + + /* Used to create handshake layer objects inside newly created channels. */ + SSL_CTX *channel_ctx; + + /* Network-side read and write BIOs. */ + BIO *net_rbio, *net_wbio; + + /* RX demuxer. We register incoming DCIDs with this. */ + QUIC_DEMUX *demux; + + /* List of all child channels. */ + OSSL_LIST(ch) channel_list; + + /* Special TSERVER channel. To be removed in the future. */ + QUIC_CHANNEL *tserver_ch; + + /* LCIDM used for incoming packet routing by DCID. */ + QUIC_LCIDM *lcidm; + + /* SRTM used for incoming packet routing by SRT. */ + QUIC_SRTM *srtm; + + /* Port-level permanent errors (causing failure state) are stored here. */ + ERR_STATE *err_state; + + /* DCID length used for incoming short header packets. */ + unsigned char rx_short_dcid_len; + /* For clients, CID length used for outgoing Initial packets. */ + unsigned char tx_init_dcid_len; + + /* Port state (QUIC_PORT_STATE_*). */ + unsigned int state : 1; + + /* Is this port created to support multiple connections? */ + unsigned int is_multi_conn : 1; + + /* Has this port sent any packet of any kind yet? */ + unsigned int have_sent_any_pkt : 1; + + /* Does this port allow incoming connections? */ + unsigned int is_server : 1; + + /* Are we on the QUIC_ENGINE linked list of ports? */ + unsigned int on_engine_list : 1; +}; + +# endif + +#endif diff --git a/libs/openssl-3/ssl/quic/quic_rcidm.c b/libs/openssl-3/ssl/quic/quic_rcidm.c new file mode 100644 index 000000000..77d8cbfcc --- /dev/null +++ b/libs/openssl-3/ssl/quic/quic_rcidm.c @@ -0,0 +1,688 @@ +/* + * 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 + */ + +#include "internal/quic_rcidm.h" +#include "internal/priority_queue.h" +#include "internal/list.h" +#include "internal/common.h" + +/* + * QUIC Remote Connection ID Manager + * ================================= + * + * We can receive an arbitrary number of RCIDs via NCID frames. Periodically, we + * may desire (for example for anti-connection fingerprinting reasons, etc.) + * to switch to a new RCID according to some arbitrary policy such as the number + * of packets we have sent. + * + * When we do this we should move to the next RCID in the sequence of received + * RCIDs ordered by sequence number. For example, if a peer sends us three NCID + * frames with sequence numbers 10, 11, 12, we should seek to consume these + * RCIDs in order. + * + * However, due to the possibility of packet reordering in the network, NCID + * frames might be received out of order. Thus if a peer sends us NCID frames + * with sequence numbers 12, 10, 11, we should still consume the RCID with + * sequence number 10 before consuming the RCIDs with sequence numbers 11 or 12. + * + * We use a priority queue for this purpose. + */ +static void rcidm_update(QUIC_RCIDM *rcidm); +static void rcidm_set_preferred_rcid(QUIC_RCIDM *rcidm, + const QUIC_CONN_ID *rcid); + +#define PACKETS_PER_RCID 10000 + +#define INITIAL_SEQ_NUM 0 +#define PREF_ADDR_SEQ_NUM 1 + +/* + * RCID + * ==== + * + * The RCID structure is used to track RCIDs which have sequence numbers (i.e., + * INITIAL, PREF_ADDR and NCID type RCIDs). The RCIDs without sequence numbers + * (Initial ODCIDs and Retry ODCIDs), hereafter referred to as unnumbered RCIDs, + * can logically be viewed as their own type of RCID but are tracked separately + * as singletons without needing a discrete structure. + * + * At any given time an RCID object is in one of these states: + * + * + * (start) + * | + * [add] + * | + * _____v_____ ___________ ____________ + * | | | | | | + * | PENDING | --[select]--> | CURRENT | --[retire]--> | RETIRING | + * |___________| |___________| |____________| + * | + * [pop] + * | + * v + * (fin) + * + * The transition through the states is monotonic and irreversible. + * The RCID object is freed when it is popped. + * + * PENDING + * Invariants: + * rcid->state == RCID_STATE_PENDING; + * rcid->pq_idx != SIZE_MAX (debug assert only); + * the RCID is not the current RCID, rcidm->cur_rcid != rcid; + * the RCID is in the priority queue; + * the RCID is not in the retiring_list. + * + * CURRENT + * Invariants: + * rcid->state == RCID_STATE_CUR; + * rcid->pq_idx == SIZE_MAX (debug assert only); + * the RCID is the current RCID, rcidm->cur_rcid == rcid; + * the RCID is not in the priority queue; + * the RCID is not in the retiring_list. + * + * RETIRING + * Invariants: + * rcid->state == RCID_STATE_RETIRING; + * rcid->pq_idx == SIZE_MAX (debug assert only); + * the RCID is not the current RCID, rcidm->cur_rcid != rcid; + * the RCID is not in the priority queue; + * the RCID is in the retiring_list. + * + * Invariant: At most one RCID object is in the CURRENT state at any one time. + * + * (If no RCID object is in the CURRENT state, this means either + * an unnumbered RCID is being used as the preferred RCID + * or we currently have no preferred RCID.) + * + * All of the above states can be considered substates of the 'ACTIVE' state + * for an RCID as specified in RFC 9000. A CID only ceases to be active + * when we send a RETIRE_CONN_ID frame, which is the responsibility of the + * user of the RCIDM and happens after the above state machine is terminated. + */ +enum { + RCID_STATE_PENDING, + RCID_STATE_CUR, + RCID_STATE_RETIRING +}; + +enum { + RCID_TYPE_INITIAL, /* CID is from an peer INITIAL packet (seq 0) */ + RCID_TYPE_PREF_ADDR, /* CID is from a preferred_address TPARAM (seq 1) */ + RCID_TYPE_NCID /* CID is from a NCID frame */ + /* + * INITIAL_ODCID and RETRY_ODCID also conceptually exist but are tracked + * separately. + */ +}; + +typedef struct rcid_st { + OSSL_LIST_MEMBER(retiring, struct rcid_st); /* valid iff RETIRING */ + + QUIC_CONN_ID cid; /* The actual CID string for this RCID */ + uint64_t seq_num; + size_t pq_idx; /* Index of entry into priority queue */ + unsigned int state : 2; /* RCID_STATE_* */ + unsigned int type : 2; /* RCID_TYPE_* */ +} RCID; + +DEFINE_PRIORITY_QUEUE_OF(RCID); +DEFINE_LIST_OF(retiring, RCID); + +/* + * RCID Manager + * ============ + * + * The following "business logic" invariants also apply to the RCIDM + * as a whole: + * + * Invariant: An RCID of INITIAL type has a sequence number of 0. + * Invariant: An RCID of PREF_ADDR type has a sequence number of 1. + * + * Invariant: There is never more than one Initial ODCID + * added throughout the lifetime of an RCIDM. + * Invariant: There is never more than one Retry ODCID + * added throughout the lifetime of an RCIDM. + * Invariant: There is never more than one INITIAL RCID created + * throughout the lifetime of an RCIDM. + * Invariant: There is never more than one PREF_ADDR RCID created + * throughout the lifetime of an RCIDM. + * Invariant: No INITIAL or PREF_ADDR RCID may be added after + * the handshake is completed. + * + */ +struct quic_rcidm_st { + /* + * The current RCID we prefer to use (value undefined if + * !have_preferred_rcid). + * + * This is preferentially set to a numbered RCID (represented by an RCID + * object) if we have one (in which case preferred_rcid == cur_rcid->cid); + * otherwise it is set to one of the unnumbered RCIDs (the Initial ODCID or + * Retry ODCID) if available (and cur_rcid == NULL). + */ + QUIC_CONN_ID preferred_rcid; + + /* + * These are initialized if the corresponding added_ flags are set. + */ + QUIC_CONN_ID initial_odcid, retry_odcid; + + /* + * Total number of packets sent since we last made a packet count-based RCID + * update decision. + */ + uint64_t packets_sent; + + /* Number of post-handshake RCID changes we have performed. */ + uint64_t num_changes; + + /* + * The Retire Prior To watermark value; max(retire_prior_to) of all received + * NCID frames. + */ + uint64_t retire_prior_to; + + /* (SORT BY seq_num ASC) -> (RCID *) */ + PRIORITY_QUEUE_OF(RCID) *rcids; + + /* + * Current RCID object we are using. This may differ from the first item in + * the priority queue if we received NCID frames out of order. For example + * if we get seq 5, switch to it immediately, then get seq 4, we want to + * keep using seq 5 until we decide to roll again rather than immediately + * switch to seq 4. Never points to an object on the retiring_list. + */ + RCID *cur_rcid; + + /* + * When a RCID becomes pending-retirement, it is moved to the retiring_list, + * then freed when it is popped from the retired queue. We use a list for + * this rather than a priority queue as the order in which items are freed + * does not matter. We always append to the tail of the list in order to + * maintain the guarantee that the head (if present) only changes when a + * caller calls pop(). + */ + OSSL_LIST(retiring) retiring_list; + + /* Number of entries on the retiring_list. */ + size_t num_retiring; + + /* preferred_rcid has been changed? */ + unsigned int preferred_rcid_changed : 1; + + /* Do we have any RCID we can use currently? */ + unsigned int have_preferred_rcid : 1; + + /* QUIC handshake has been completed? */ + unsigned int handshake_complete : 1; + + /* odcid was set (not necessarily still valid as a RCID)? */ + unsigned int added_initial_odcid : 1; + /* retry_odcid was set (not necessarily still valid as a RCID?) */ + unsigned int added_retry_odcid : 1; + /* An initial RCID was added as an RCID structure? */ + unsigned int added_initial_rcid : 1; + /* Has a RCID roll been manually requested? */ + unsigned int roll_requested : 1; +}; + +/* + * Caller must periodically pop retired RCIDs and handle them. If the caller + * fails to do so, fail safely rather than start exhibiting integer rollover. + * Limit the total number of numbered RCIDs to an implausibly large but safe + * value. + */ +#define MAX_NUMBERED_RCIDS (SIZE_MAX / 2) + +static void rcidm_transition_rcid(QUIC_RCIDM *rcidm, RCID *rcid, + unsigned int state); + +/* Check invariants of an RCID */ +static void rcidm_check_rcid(QUIC_RCIDM *rcidm, RCID *rcid) +{ + assert(rcid->state == RCID_STATE_PENDING + || rcid->state == RCID_STATE_CUR + || rcid->state == RCID_STATE_RETIRING); + assert((rcid->state == RCID_STATE_PENDING) + == (rcid->pq_idx != SIZE_MAX)); + assert((rcid->state == RCID_STATE_CUR) + == (rcidm->cur_rcid == rcid)); + assert((ossl_list_retiring_next(rcid) != NULL + || ossl_list_retiring_prev(rcid) != NULL + || ossl_list_retiring_head(&rcidm->retiring_list) == rcid) + == (rcid->state == RCID_STATE_RETIRING)); + assert(rcid->type != RCID_TYPE_INITIAL || rcid->seq_num == 0); + assert(rcid->type != RCID_TYPE_PREF_ADDR || rcid->seq_num == 1); + assert(rcid->seq_num <= OSSL_QUIC_VLINT_MAX); + assert(rcid->cid.id_len > 0 && rcid->cid.id_len <= QUIC_MAX_CONN_ID_LEN); + assert(rcid->seq_num >= rcidm->retire_prior_to + || rcid->state == RCID_STATE_RETIRING); + assert(rcidm->num_changes == 0 || rcidm->handshake_complete); + assert(rcid->state != RCID_STATE_RETIRING || rcidm->num_retiring > 0); +} + +static int rcid_cmp(const RCID *a, const RCID *b) +{ + if (a->seq_num < b->seq_num) + return -1; + if (a->seq_num > b->seq_num) + return 1; + return 0; +} + +QUIC_RCIDM *ossl_quic_rcidm_new(const QUIC_CONN_ID *initial_odcid) +{ + QUIC_RCIDM *rcidm; + + if ((rcidm = OPENSSL_zalloc(sizeof(*rcidm))) == NULL) + return NULL; + + if ((rcidm->rcids = ossl_pqueue_RCID_new(rcid_cmp)) == NULL) { + OPENSSL_free(rcidm); + return NULL; + } + + if (initial_odcid != NULL) { + rcidm->initial_odcid = *initial_odcid; + rcidm->added_initial_odcid = 1; + } + + rcidm_update(rcidm); + return rcidm; +} + +void ossl_quic_rcidm_free(QUIC_RCIDM *rcidm) +{ + RCID *rcid, *rnext; + + if (rcidm == NULL) + return; + + OPENSSL_free(rcidm->cur_rcid); + while ((rcid = ossl_pqueue_RCID_pop(rcidm->rcids)) != NULL) + OPENSSL_free(rcid); + + LIST_FOREACH_DELSAFE(rcid, rnext, retiring, &rcidm->retiring_list) + OPENSSL_free(rcid); + + ossl_pqueue_RCID_free(rcidm->rcids); + OPENSSL_free(rcidm); +} + +static void rcidm_set_preferred_rcid(QUIC_RCIDM *rcidm, + const QUIC_CONN_ID *rcid) +{ + if (rcid == NULL) { + rcidm->preferred_rcid_changed = 1; + rcidm->have_preferred_rcid = 0; + return; + } + + if (ossl_quic_conn_id_eq(&rcidm->preferred_rcid, rcid)) + return; + + rcidm->preferred_rcid = *rcid; + rcidm->preferred_rcid_changed = 1; + rcidm->have_preferred_rcid = 1; +} + +/* + * RCID Lifecycle Management + * ========================= + */ +static RCID *rcidm_create_rcid(QUIC_RCIDM *rcidm, uint64_t seq_num, + const QUIC_CONN_ID *cid, + unsigned int type) +{ + RCID *rcid; + + if (cid->id_len < 1 || cid->id_len > QUIC_MAX_CONN_ID_LEN + || seq_num > OSSL_QUIC_VLINT_MAX + || ossl_pqueue_RCID_num(rcidm->rcids) + rcidm->num_retiring + > MAX_NUMBERED_RCIDS) + return NULL; + + if ((rcid = OPENSSL_zalloc(sizeof(*rcid))) == NULL) + return NULL; + + rcid->seq_num = seq_num; + rcid->cid = *cid; + rcid->type = type; + + if (rcid->seq_num >= rcidm->retire_prior_to) { + rcid->state = RCID_STATE_PENDING; + + if (!ossl_pqueue_RCID_push(rcidm->rcids, rcid, &rcid->pq_idx)) { + OPENSSL_free(rcid); + return NULL; + } + } else { + /* RCID is immediately retired upon creation. */ + rcid->state = RCID_STATE_RETIRING; + rcid->pq_idx = SIZE_MAX; + ossl_list_retiring_insert_tail(&rcidm->retiring_list, rcid); + ++rcidm->num_retiring; + } + + rcidm_check_rcid(rcidm, rcid); + return rcid; +} + +static void rcidm_transition_rcid(QUIC_RCIDM *rcidm, RCID *rcid, + unsigned int state) +{ + unsigned int old_state = rcid->state; + + assert(state >= old_state && state <= RCID_STATE_RETIRING); + rcidm_check_rcid(rcidm, rcid); + if (state == old_state) + return; + + if (rcidm->cur_rcid != NULL && state == RCID_STATE_CUR) { + rcidm_transition_rcid(rcidm, rcidm->cur_rcid, RCID_STATE_RETIRING); + assert(rcidm->cur_rcid == NULL); + } + + if (old_state == RCID_STATE_PENDING) { + ossl_pqueue_RCID_remove(rcidm->rcids, rcid->pq_idx); + rcid->pq_idx = SIZE_MAX; + } + + rcid->state = state; + + if (state == RCID_STATE_CUR) { + rcidm->cur_rcid = rcid; + } else if (state == RCID_STATE_RETIRING) { + if (old_state == RCID_STATE_CUR) + rcidm->cur_rcid = NULL; + + ossl_list_retiring_insert_tail(&rcidm->retiring_list, rcid); + ++rcidm->num_retiring; + } + + rcidm_check_rcid(rcidm, rcid); +} + +static void rcidm_free_rcid(QUIC_RCIDM *rcidm, RCID *rcid) +{ + if (rcid == NULL) + return; + + rcidm_check_rcid(rcidm, rcid); + + switch (rcid->state) { + case RCID_STATE_PENDING: + ossl_pqueue_RCID_remove(rcidm->rcids, rcid->pq_idx); + break; + case RCID_STATE_CUR: + rcidm->cur_rcid = NULL; + break; + case RCID_STATE_RETIRING: + ossl_list_retiring_remove(&rcidm->retiring_list, rcid); + --rcidm->num_retiring; + break; + default: + assert(0); + break; + } + + OPENSSL_free(rcid); +} + +static void rcidm_handle_retire_prior_to(QUIC_RCIDM *rcidm, + uint64_t retire_prior_to) +{ + RCID *rcid; + + if (retire_prior_to <= rcidm->retire_prior_to) + return; + + /* + * Retire the current RCID (if any) if it is affected. + */ + if (rcidm->cur_rcid != NULL && rcidm->cur_rcid->seq_num < retire_prior_to) + rcidm_transition_rcid(rcidm, rcidm->cur_rcid, RCID_STATE_RETIRING); + + /* + * Any other RCIDs needing retirement will be at the start of the priority + * queue, so just stop once we see a higher sequence number exceeding the + * threshold. + */ + while ((rcid = ossl_pqueue_RCID_peek(rcidm->rcids)) != NULL + && rcid->seq_num < retire_prior_to) + rcidm_transition_rcid(rcidm, rcid, RCID_STATE_RETIRING); + + rcidm->retire_prior_to = retire_prior_to; +} + +/* + * Decision Logic + * ============== + */ + +static void rcidm_roll(QUIC_RCIDM *rcidm) +{ + RCID *rcid; + + if ((rcid = ossl_pqueue_RCID_peek(rcidm->rcids)) == NULL) + return; + + rcidm_transition_rcid(rcidm, rcid, RCID_STATE_CUR); + + ++rcidm->num_changes; + rcidm->roll_requested = 0; + + if (rcidm->packets_sent >= PACKETS_PER_RCID) + rcidm->packets_sent %= PACKETS_PER_RCID; + else + rcidm->packets_sent = 0; +} + +static void rcidm_update(QUIC_RCIDM *rcidm) +{ + RCID *rcid; + + /* + * If we have no current numbered RCID but have one or more pending, use it. + */ + if (rcidm->cur_rcid == NULL + && (rcid = ossl_pqueue_RCID_peek(rcidm->rcids)) != NULL) { + rcidm_transition_rcid(rcidm, rcid, RCID_STATE_CUR); + assert(rcidm->cur_rcid != NULL); + } + + /* Prefer use of any current numbered RCID we have, if possible. */ + if (rcidm->cur_rcid != NULL) { + rcidm_check_rcid(rcidm, rcidm->cur_rcid); + rcidm_set_preferred_rcid(rcidm, &rcidm->cur_rcid->cid); + return; + } + + /* + * If there are no RCIDs from NCID frames we can use, go through the various + * kinds of bootstrapping RCIDs we can use in order of priority. + */ + if (rcidm->added_retry_odcid && !rcidm->handshake_complete) { + rcidm_set_preferred_rcid(rcidm, &rcidm->retry_odcid); + return; + } + + if (rcidm->added_initial_odcid && !rcidm->handshake_complete) { + rcidm_set_preferred_rcid(rcidm, &rcidm->initial_odcid); + return; + } + + /* We don't know of any usable RCIDs */ + rcidm_set_preferred_rcid(rcidm, NULL); +} + +static int rcidm_should_roll(QUIC_RCIDM *rcidm) +{ + /* + * Always switch as soon as possible if handshake completes; + * and every n packets after handshake completes or the last roll; and + * whenever manually requested. + */ + return rcidm->handshake_complete + && (rcidm->num_changes == 0 + || rcidm->packets_sent >= PACKETS_PER_RCID + || rcidm->roll_requested); +} + +static void rcidm_tick(QUIC_RCIDM *rcidm) +{ + if (rcidm_should_roll(rcidm)) + rcidm_roll(rcidm); + + rcidm_update(rcidm); +} + +/* + * Events + * ====== + */ +void ossl_quic_rcidm_on_handshake_complete(QUIC_RCIDM *rcidm) +{ + if (rcidm->handshake_complete) + return; + + rcidm->handshake_complete = 1; + rcidm_tick(rcidm); +} + +void ossl_quic_rcidm_on_packet_sent(QUIC_RCIDM *rcidm, uint64_t num_packets) +{ + if (num_packets == 0) + return; + + rcidm->packets_sent += num_packets; + rcidm_tick(rcidm); +} + +void ossl_quic_rcidm_request_roll(QUIC_RCIDM *rcidm) +{ + rcidm->roll_requested = 1; + rcidm_tick(rcidm); +} + +/* + * Mutation Operations + * =================== + */ +int ossl_quic_rcidm_add_from_initial(QUIC_RCIDM *rcidm, + const QUIC_CONN_ID *rcid) +{ + RCID *rcid_obj; + + if (rcidm->added_initial_rcid || rcidm->handshake_complete) + return 0; + + rcid_obj = rcidm_create_rcid(rcidm, INITIAL_SEQ_NUM, + rcid, RCID_TYPE_INITIAL); + if (rcid_obj == NULL) + return 0; + + rcidm->added_initial_rcid = 1; + rcidm_tick(rcidm); + return 1; +} + +int ossl_quic_rcidm_add_from_server_retry(QUIC_RCIDM *rcidm, + const QUIC_CONN_ID *retry_odcid) +{ + if (rcidm->added_retry_odcid || rcidm->handshake_complete) + return 0; + + rcidm->retry_odcid = *retry_odcid; + rcidm->added_retry_odcid = 1; + rcidm_tick(rcidm); + return 1; +} + +int ossl_quic_rcidm_add_from_ncid(QUIC_RCIDM *rcidm, + const OSSL_QUIC_FRAME_NEW_CONN_ID *ncid) +{ + RCID *rcid; + + rcid = rcidm_create_rcid(rcidm, ncid->seq_num, &ncid->conn_id, RCID_TYPE_NCID); + if (rcid == NULL) + return 0; + + rcidm_handle_retire_prior_to(rcidm, ncid->retire_prior_to); + rcidm_tick(rcidm); + return 1; +} + +/* + * Queries + * ======= + */ + +static int rcidm_get_retire(QUIC_RCIDM *rcidm, uint64_t *seq_num, int peek) +{ + RCID *rcid = ossl_list_retiring_head(&rcidm->retiring_list); + + if (rcid == NULL) + return 0; + + if (seq_num != NULL) + *seq_num = rcid->seq_num; + + if (!peek) + rcidm_free_rcid(rcidm, rcid); + + return 1; +} + +int ossl_quic_rcidm_pop_retire_seq_num(QUIC_RCIDM *rcidm, + uint64_t *seq_num) +{ + return rcidm_get_retire(rcidm, seq_num, /*peek=*/0); +} + +int ossl_quic_rcidm_peek_retire_seq_num(QUIC_RCIDM *rcidm, + uint64_t *seq_num) +{ + return rcidm_get_retire(rcidm, seq_num, /*peek=*/1); +} + +int ossl_quic_rcidm_get_preferred_tx_dcid(QUIC_RCIDM *rcidm, + QUIC_CONN_ID *tx_dcid) +{ + if (!rcidm->have_preferred_rcid) + return 0; + + *tx_dcid = rcidm->preferred_rcid; + return 1; +} + +int ossl_quic_rcidm_get_preferred_tx_dcid_changed(QUIC_RCIDM *rcidm, + int clear) +{ + int r = rcidm->preferred_rcid_changed; + + if (clear) + rcidm->preferred_rcid_changed = 0; + + return r; +} + +size_t ossl_quic_rcidm_get_num_active(const QUIC_RCIDM *rcidm) +{ + return ossl_pqueue_RCID_num(rcidm->rcids) + + (rcidm->cur_rcid != NULL ? 1 : 0) + + ossl_quic_rcidm_get_num_retiring(rcidm); +} + +size_t ossl_quic_rcidm_get_num_retiring(const QUIC_RCIDM *rcidm) +{ + return rcidm->num_retiring; +} diff --git a/libs/openssl-3/ssl/quic/quic_record_rx.c b/libs/openssl-3/ssl/quic/quic_record_rx.c index 4d0493baf..722b957a4 100644 --- a/libs/openssl-3/ssl/quic/quic_record_rx.c +++ b/libs/openssl-3/ssl/quic/quic_record_rx.c @@ -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 @@ -67,6 +67,12 @@ struct rxe_st { */ uint64_t key_epoch; + /* + * Monotonically increases with each datagram received. + * For diagnostic use only. + */ + uint64_t datagram_id; + /* * alloc_len allocated bytes (of which data_len bytes are valid) follow this * structure. @@ -167,19 +173,17 @@ struct ossl_qrx_st { SSL *msg_callback_ssl; }; -static void qrx_on_rx(QUIC_URXE *urxe, void *arg); - OSSL_QRX *ossl_qrx_new(const OSSL_QRX_ARGS *args) { OSSL_QRX *qrx; size_t i; if (args->demux == NULL || args->max_deferred == 0) - return 0; + return NULL; qrx = OPENSSL_zalloc(sizeof(OSSL_QRX)); if (qrx == NULL) - return 0; + return NULL; for (i = 0; i < OSSL_NELEM(qrx->largest_pn); ++i) qrx->largest_pn[i] = args->init_largest_pn[i]; @@ -222,9 +226,6 @@ void ossl_qrx_free(OSSL_QRX *qrx) if (qrx == NULL) return; - /* Unregister from the RX DEMUX. */ - ossl_quic_demux_unregister_by_cb(qrx->demux, qrx_on_rx, qrx); - /* Free RXE queue data. */ qrx_cleanup_rxl(&qrx->rx_free); qrx_cleanup_rxl(&qrx->rx_pending); @@ -252,28 +253,6 @@ void ossl_qrx_inject_urxe(OSSL_QRX *qrx, QUIC_URXE *urxe) qrx->msg_callback_arg); } -static void qrx_on_rx(QUIC_URXE *urxe, void *arg) -{ - OSSL_QRX *qrx = arg; - - ossl_qrx_inject_urxe(qrx, urxe); -} - -int ossl_qrx_add_dst_conn_id(OSSL_QRX *qrx, - const QUIC_CONN_ID *dst_conn_id) -{ - return ossl_quic_demux_register(qrx->demux, - dst_conn_id, - qrx_on_rx, - qrx); -} - -int ossl_qrx_remove_dst_conn_id(OSSL_QRX *qrx, - const QUIC_CONN_ID *dst_conn_id) -{ - return ossl_quic_demux_unregister(qrx->demux, dst_conn_id); -} - static void qrx_requeue_deferred(OSSL_QRX *qrx) { QUIC_URXE *e; @@ -892,6 +871,7 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe, rxe->peer = urxe->peer; rxe->local = urxe->local; rxe->time = urxe->time; + rxe->datagram_id = urxe->datagram_id; /* Move RXE to pending. */ ossl_list_rxe_remove(&qrx->rx_free, rxe); @@ -1073,9 +1053,10 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe, qrx->largest_pn[pn_space] = rxe->pn; /* Copy across network addresses and RX time from URXE to RXE. */ - rxe->peer = urxe->peer; - rxe->local = urxe->local; - rxe->time = urxe->time; + rxe->peer = urxe->peer; + rxe->local = urxe->local; + rxe->time = urxe->time; + rxe->datagram_id = urxe->datagram_id; /* Move RXE to pending. */ ossl_list_rxe_remove(&qrx->rx_free, rxe); @@ -1254,6 +1235,7 @@ int ossl_qrx_read_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT **ppkt) rxe->pkt.local = BIO_ADDR_family(&rxe->local) != AF_UNSPEC ? &rxe->local : NULL; rxe->pkt.key_epoch = rxe->key_epoch; + rxe->pkt.datagram_id = rxe->datagram_id; rxe->pkt.qrx = qrx; *ppkt = &rxe->pkt; diff --git a/libs/openssl-3/ssl/quic/quic_record_tx.c b/libs/openssl-3/ssl/quic/quic_record_tx.c index c01abed0d..cda684245 100644 --- a/libs/openssl-3/ssl/quic/quic_record_tx.c +++ b/libs/openssl-3/ssl/quic/quic_record_tx.c @@ -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 @@ -8,6 +8,7 @@ */ #include "internal/quic_record_tx.h" +#include "internal/qlog_event_helpers.h" #include "internal/bio_addr.h" #include "internal/common.h" #include "quic_record_shared.h" @@ -60,6 +61,10 @@ struct ossl_qtx_st { /* TX BIO. */ BIO *bio; + /* QLOG instance retrieval callback if in use, or NULL. */ + QLOG *(*get_qlog_cb)(void *arg); + void *get_qlog_cb_arg; + /* TX maximum datagram payload length. */ size_t mdpl; @@ -91,6 +96,9 @@ struct ossl_qtx_st { */ uint64_t epoch_pkt_count; + /* Datagram counter. Increases monotonically per datagram (not per packet). */ + uint64_t datagram_count; + ossl_mutate_packet_cb mutatecb; ossl_finish_mutate_cb finishmutatecb; void *mutatearg; @@ -117,6 +125,9 @@ OSSL_QTX *ossl_qtx_new(const OSSL_QTX_ARGS *args) qtx->propq = args->propq; qtx->bio = args->bio; qtx->mdpl = args->mdpl; + qtx->get_qlog_cb = args->get_qlog_cb; + qtx->get_qlog_cb_arg = args->get_qlog_cb_arg; + return qtx; } @@ -159,6 +170,13 @@ void ossl_qtx_set_mutator(OSSL_QTX *qtx, ossl_mutate_packet_cb mutatecb, qtx->mutatearg = mutatearg; } +void ossl_qtx_set_qlog_cb(OSSL_QTX *qtx, QLOG *(*get_qlog_cb)(void *arg), + void *get_qlog_cb_arg) +{ + qtx->get_qlog_cb = get_qlog_cb; + qtx->get_qlog_cb_arg = get_qlog_cb_arg; +} + int ossl_qtx_provide_secret(OSSL_QTX *qtx, uint32_t enc_level, uint32_t suite_id, @@ -579,7 +597,8 @@ static int qtx_encrypt_into_txe(OSSL_QTX *qtx, struct iovec_cur *cur, TXE *txe, * process. */ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe, - uint32_t enc_level) + uint32_t enc_level, QUIC_PKT_HDR *hdr, + const OSSL_QTX_IOVEC *iovec, size_t num_iovec) { int ret, needs_encrypt; size_t hdr_len, pred_hdr_len, payload_len, pkt_len, space_left; @@ -588,15 +607,12 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe, QUIC_PKT_HDR_PTRS ptrs; unsigned char *hdr_start; OSSL_QRL_ENC_LEVEL *el = NULL; - QUIC_PKT_HDR *hdr; - const OSSL_QTX_IOVEC *iovec; - size_t num_iovec; /* * Determine if the packet needs encryption and the minimum conceivable * serialization length. */ - if (!ossl_quic_pkt_type_is_encrypted(pkt->hdr->type)) { + if (!ossl_quic_pkt_type_is_encrypted(hdr->type)) { needs_encrypt = 0; min_len = QUIC_MIN_VALID_PKT_LEN; } else { @@ -616,21 +632,8 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe, } /* Set some fields in the header we are responsible for. */ - if (pkt->hdr->type == QUIC_PKT_TYPE_1RTT) - pkt->hdr->key_phase = (unsigned char)(el->key_epoch & 1); - - /* If we are running tests then mutate_packet may be non NULL */ - if (qtx->mutatecb != NULL) { - if (!qtx->mutatecb(pkt->hdr, pkt->iovec, pkt->num_iovec, &hdr, - &iovec, &num_iovec, qtx->mutatearg)) { - ret = QTX_FAIL_GENERIC; - goto err; - } - } else { - hdr = pkt->hdr; - iovec = pkt->iovec; - num_iovec = pkt->num_iovec; - } + if (hdr->type == QUIC_PKT_TYPE_1RTT) + hdr->key_phase = (unsigned char)(el->key_epoch & 1); /* Walk the iovecs to determine actual input payload length. */ iovec_cur_init(&cur, iovec, num_iovec); @@ -711,8 +714,6 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe, assert(txe->data_len - orig_data_len == pkt_len); } - if (qtx->finishmutatecb != NULL) - qtx->finishmutatecb(qtx->mutatearg); return 1; err: @@ -721,8 +722,6 @@ static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe, * TXE. */ txe->data_len = orig_data_len; - if (qtx->finishmutatecb != NULL) - qtx->finishmutatecb(qtx->mutatearg); return ret; } @@ -744,6 +743,46 @@ static TXE *qtx_ensure_cons(OSSL_QTX *qtx) return txe; } +static QLOG *qtx_get_qlog(OSSL_QTX *qtx) +{ + if (qtx->get_qlog_cb == NULL) + return NULL; + + return qtx->get_qlog_cb(qtx->get_qlog_cb_arg); +} + +static int qtx_mutate_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe, + uint32_t enc_level) +{ + int ret; + QUIC_PKT_HDR *hdr; + const OSSL_QTX_IOVEC *iovec; + size_t num_iovec; + + /* If we are running tests then mutate_packet may be non NULL */ + if (qtx->mutatecb != NULL) { + if (!qtx->mutatecb(pkt->hdr, pkt->iovec, pkt->num_iovec, &hdr, + &iovec, &num_iovec, qtx->mutatearg)) + return QTX_FAIL_GENERIC; + } else { + hdr = pkt->hdr; + iovec = pkt->iovec; + num_iovec = pkt->num_iovec; + } + + ret = qtx_write(qtx, pkt, txe, enc_level, + hdr, iovec, num_iovec); + if (ret == 1) + ossl_qlog_event_transport_packet_sent(qtx_get_qlog(qtx), hdr, pkt->pn, + iovec, num_iovec, + qtx->datagram_count); + + if (qtx->finishmutatecb != NULL) + qtx->finishmutatecb(qtx->mutatearg); + + return ret; +} + static int addr_eq(const BIO_ADDR *a, const BIO_ADDR *b) { return ((a == NULL || BIO_ADDR_family(a) == AF_UNSPEC) @@ -814,7 +853,7 @@ int ossl_qtx_write_pkt(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt) BIO_ADDR_clear(&txe->local); } - ret = qtx_write(qtx, pkt, txe, enc_level); + ret = qtx_mutate_write(qtx, pkt, txe, enc_level); if (ret == 1) { break; } else if (ret == QTX_FAIL_INSUFFICIENT_LEN) { @@ -874,6 +913,7 @@ void ossl_qtx_finish_dgram(OSSL_QTX *qtx) qtx->cons = NULL; qtx->cons_count = 0; + ++qtx->datagram_count; } static void txe_to_msg(TXE *txe, BIO_MSG *msg) diff --git a/libs/openssl-3/ssl/quic/quic_rx_depack.c b/libs/openssl-3/ssl/quic/quic_rx_depack.c index 97c6d6095..58a8edf03 100644 --- a/libs/openssl-3/ssl/quic/quic_rx_depack.c +++ b/libs/openssl-3/ssl/quic/quic_rx_depack.c @@ -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 @@ -48,7 +48,7 @@ static int depack_do_frame_ping(PACKET *pkt, QUIC_CHANNEL *ch, /* We ignore this frame, apart from eliciting an ACK */ if (!ossl_quic_wire_decode_frame_ping(pkt)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_PING, "decode error"); return 0; @@ -115,7 +115,7 @@ static int depack_do_frame_ack(PACKET *pkt, QUIC_CHANNEL *ch, * epoch has not incremented and ch->rxku_expected is still 1. */ ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_KEY_UPDATE_ERROR, + OSSL_QUIC_ERR_KEY_UPDATE_ERROR, frame_type, "acked packet which initiated a " "key update without a " @@ -132,7 +132,7 @@ static int depack_do_frame_ack(PACKET *pkt, QUIC_CHANNEL *ch, malformed: ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, frame_type, "decode error"); return 0; @@ -148,7 +148,7 @@ static int depack_do_frame_reset_stream(PACKET *pkt, if (!ossl_quic_wire_decode_frame_reset_stream(pkt, &frame_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_RESET_STREAM, "decode error"); return 0; @@ -164,7 +164,7 @@ static int depack_do_frame_reset_stream(PACKET *pkt, if (!ossl_quic_stream_has_recv(stream)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_ERR_STREAM_STATE_ERROR, OSSL_QUIC_FRAME_TYPE_RESET_STREAM, "RESET_STREAM frame for " "TX only stream"); @@ -184,7 +184,7 @@ static int depack_do_frame_reset_stream(PACKET *pkt, if (!ossl_quic_rxfc_on_rx_stream_frame(&stream->rxfc, frame_data.final_size, /*is_fin=*/1)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, OSSL_QUIC_FRAME_TYPE_RESET_STREAM, "internal error (flow control)"); return 0; @@ -192,7 +192,7 @@ static int depack_do_frame_reset_stream(PACKET *pkt, /* Has a flow control error occurred? */ fce = ossl_quic_rxfc_get_error(&stream->rxfc, 0); - if (fce != QUIC_ERR_NO_ERROR) { + if (fce != OSSL_QUIC_ERR_NO_ERROR) { ossl_quic_channel_raise_protocol_error(ch, fce, OSSL_QUIC_FRAME_TYPE_RESET_STREAM, @@ -223,7 +223,7 @@ static int depack_do_frame_stop_sending(PACKET *pkt, if (!ossl_quic_wire_decode_frame_stop_sending(pkt, &frame_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_STOP_SENDING, "decode error"); return 0; @@ -239,7 +239,7 @@ static int depack_do_frame_stop_sending(PACKET *pkt, if (!ossl_quic_stream_has_send(stream)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_ERR_STREAM_STATE_ERROR, OSSL_QUIC_FRAME_TYPE_STOP_SENDING, "STOP_SENDING frame for " "RX only stream"); @@ -272,7 +272,7 @@ static int depack_do_frame_crypto(PACKET *pkt, QUIC_CHANNEL *ch, if (!ossl_quic_wire_decode_frame_crypto(pkt, 0, &f)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_CRYPTO, "decode error"); return 0; @@ -295,14 +295,14 @@ static int depack_do_frame_crypto(PACKET *pkt, QUIC_CHANNEL *ch, if (!ossl_quic_rxfc_on_rx_stream_frame(rxfc, f.offset + f.len, /*is_fin=*/0)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, OSSL_QUIC_FRAME_TYPE_CRYPTO, "internal error (crypto RXFC)"); return 0; } - if (ossl_quic_rxfc_get_error(rxfc, 0) != QUIC_ERR_NO_ERROR) { - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_CRYPTO_BUFFER_EXCEEDED, + if (ossl_quic_rxfc_get_error(rxfc, 0) != OSSL_QUIC_ERR_NO_ERROR) { + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED, OSSL_QUIC_FRAME_TYPE_CRYPTO, "exceeded maximum crypto buffer"); return 0; @@ -311,7 +311,7 @@ static int depack_do_frame_crypto(PACKET *pkt, QUIC_CHANNEL *ch, if (!ossl_quic_rstream_queue_data(rstream, parent_pkt, f.offset, f.data, f.len, 0)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, OSSL_QUIC_FRAME_TYPE_CRYPTO, "internal error (rstream queue)"); return 0; @@ -331,7 +331,7 @@ static int depack_do_frame_new_token(PACKET *pkt, QUIC_CHANNEL *ch, if (!ossl_quic_wire_decode_frame_new_token(pkt, &token, &token_len)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN, "decode error"); return 0; @@ -344,7 +344,7 @@ static int depack_do_frame_new_token(PACKET *pkt, QUIC_CHANNEL *ch, * FRAME_ENCODING_ERROR." */ ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN, "zero-length NEW_TOKEN"); return 0; @@ -425,14 +425,14 @@ static int depack_do_implicit_stream_create(QUIC_CHANNEL *ch, stream_ordinal + 1, /*is_fin=*/0)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, frame_type, "internal error (stream count RXFC)"); return 0; } - if (ossl_quic_rxfc_get_error(max_streams_fc, 0) != QUIC_ERR_NO_ERROR) { - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_STREAM_LIMIT_ERROR, + if (ossl_quic_rxfc_get_error(max_streams_fc, 0) != OSSL_QUIC_ERR_NO_ERROR) { + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, frame_type, "exceeded maximum allowed streams"); return 0; @@ -450,7 +450,7 @@ static int depack_do_implicit_stream_create(QUIC_CHANNEL *ch, stream = ossl_quic_channel_new_stream_remote(ch, cur_stream_id); if (stream == NULL) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, frame_type, "internal error (stream allocation)"); return 0; @@ -472,7 +472,7 @@ static int depack_do_implicit_stream_create(QUIC_CHANNEL *ch, * violation. */ ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_ERR_STREAM_STATE_ERROR, frame_type, "STREAM frame for nonexistent " "stream"); @@ -507,7 +507,7 @@ static int depack_do_frame_stream(PACKET *pkt, QUIC_CHANNEL *ch, if (!ossl_quic_wire_decode_frame_stream(pkt, 0, &frame_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, frame_type, "decode error"); return 0; @@ -526,7 +526,7 @@ static int depack_do_frame_stream(PACKET *pkt, QUIC_CHANNEL *ch, if (!ossl_quic_stream_has_recv(stream)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_ERR_STREAM_STATE_ERROR, frame_type, "STREAM frame for TX only " "stream"); @@ -538,7 +538,7 @@ static int depack_do_frame_stream(PACKET *pkt, QUIC_CHANNEL *ch, frame_data.offset + frame_data.len, frame_data.is_fin)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, frame_type, "internal error (flow control)"); return 0; @@ -546,7 +546,7 @@ static int depack_do_frame_stream(PACKET *pkt, QUIC_CHANNEL *ch, /* Has a flow control error occurred? */ fce = ossl_quic_rxfc_get_error(&stream->rxfc, 0); - if (fce != QUIC_ERR_NO_ERROR) { + if (fce != OSSL_QUIC_ERR_NO_ERROR) { ossl_quic_channel_raise_protocol_error(ch, fce, frame_type, @@ -610,7 +610,7 @@ static int depack_do_frame_stream(PACKET *pkt, QUIC_CHANNEL *ch, frame_data.len, frame_data.is_fin)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, frame_type, "internal error (rstream queue)"); return 0; @@ -625,7 +625,7 @@ static int depack_do_frame_stream(PACKET *pkt, QUIC_CHANNEL *ch, if (stream->recv_state == QUIC_RSTREAM_STATE_SIZE_KNOWN && !ossl_quic_rstream_available(stream->rstream, &rs_avail, &rs_fin)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, frame_type, "internal error (rstream available)"); return 0; @@ -673,7 +673,7 @@ static int depack_do_frame_max_data(PACKET *pkt, QUIC_CHANNEL *ch, if (!ossl_quic_wire_decode_frame_max_data(pkt, &max_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_MAX_DATA, "decode error"); return 0; @@ -695,7 +695,7 @@ static int depack_do_frame_max_stream_data(PACKET *pkt, if (!ossl_quic_wire_decode_frame_max_stream_data(pkt, &stream_id, &max_stream_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA, "decode error"); return 0; @@ -711,7 +711,7 @@ static int depack_do_frame_max_stream_data(PACKET *pkt, if (!ossl_quic_stream_has_send(stream)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_ERR_STREAM_STATE_ERROR, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA, "MAX_STREAM_DATA for TX only " "stream"); @@ -732,7 +732,7 @@ static int depack_do_frame_max_streams(PACKET *pkt, if (!ossl_quic_wire_decode_frame_max_streams(pkt, &max_streams)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, frame_type, "decode error"); return 0; @@ -740,7 +740,7 @@ static int depack_do_frame_max_streams(PACKET *pkt, if (max_streams > (((uint64_t)1) << 60)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, frame_type, "invalid max streams value"); return 0; @@ -763,7 +763,7 @@ static int depack_do_frame_max_streams(PACKET *pkt, break; default: ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, frame_type, "decode error"); return 0; @@ -780,7 +780,7 @@ static int depack_do_frame_data_blocked(PACKET *pkt, if (!ossl_quic_wire_decode_frame_data_blocked(pkt, &max_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED, "decode error"); return 0; @@ -801,7 +801,7 @@ static int depack_do_frame_stream_data_blocked(PACKET *pkt, if (!ossl_quic_wire_decode_frame_stream_data_blocked(pkt, &stream_id, &max_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED, "decode error"); return 0; @@ -826,7 +826,7 @@ static int depack_do_frame_stream_data_blocked(PACKET *pkt, * STREAM_STATE_ERROR." */ ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_ERR_STREAM_STATE_ERROR, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED, "STREAM_DATA_BLOCKED frame for " "TX only stream"); @@ -846,7 +846,7 @@ static int depack_do_frame_streams_blocked(PACKET *pkt, if (!ossl_quic_wire_decode_frame_streams_blocked(pkt, &max_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, frame_type, "decode error"); return 0; @@ -860,7 +860,7 @@ static int depack_do_frame_streams_blocked(PACKET *pkt, * error of type STREAM_LIMIT_ERROR or FRAME_ENCODING_ERROR." */ ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_STREAM_LIMIT_ERROR, + OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, frame_type, "invalid stream count limit"); return 0; @@ -878,7 +878,7 @@ static int depack_do_frame_new_conn_id(PACKET *pkt, if (!ossl_quic_wire_decode_frame_new_conn_id(pkt, &frame_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, "decode error"); return 0; @@ -897,7 +897,7 @@ static int depack_do_frame_retire_conn_id(PACKET *pkt, if (!ossl_quic_wire_decode_frame_retire_conn_id(pkt, &seq_num)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID, "decode error"); return 0; @@ -918,7 +918,7 @@ static int depack_do_frame_retire_conn_id(PACKET *pkt, */ if (!ch->is_server) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID, "conn has zero-length CID"); return 0; @@ -943,7 +943,7 @@ static int depack_do_frame_path_challenge(PACKET *pkt, if (!ossl_quic_wire_decode_frame_path_challenge(pkt, &frame_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE, "decode error"); return 0; @@ -981,7 +981,7 @@ static int depack_do_frame_path_challenge(PACKET *pkt, err: OPENSSL_free(encoded); - ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, + ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE, "internal error"); return 0; @@ -995,7 +995,7 @@ static int depack_do_frame_path_response(PACKET *pkt, if (!ossl_quic_wire_decode_frame_path_response(pkt, &frame_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE, "decode error"); return 0; @@ -1013,7 +1013,7 @@ static int depack_do_frame_conn_close(PACKET *pkt, QUIC_CHANNEL *ch, if (!ossl_quic_wire_decode_frame_conn_close(pkt, &frame_data)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, frame_type, "decode error"); return 0; @@ -1030,7 +1030,7 @@ static int depack_do_frame_handshake_done(PACKET *pkt, if (!ossl_quic_wire_decode_frame_handshake_done(pkt)) { /* This can fail only with an internal error. */ ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_ERR_INTERNAL_ERROR, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE, "internal error (decode frame handshake done)"); return 0; @@ -1056,7 +1056,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, * PROTOCOL_VIOLATION. */ ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, "empty packet payload"); return 0; @@ -1073,7 +1073,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (!ossl_quic_wire_peek_frame_header(pkt, &frame_type, &was_minimal)) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, "malformed frame header"); return 0; @@ -1081,7 +1081,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (!was_minimal) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "non-minimal frame type encoding"); return 0; @@ -1122,7 +1122,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, /* ACK frames are valid everywhere except in 0RTT packets */ if (pkt_type == QUIC_PKT_TYPE_0RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "ACK not valid in 0-RTT"); return 0; @@ -1137,7 +1137,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "RESET_STREAM not valid in " "INITIAL/HANDSHAKE"); @@ -1151,7 +1151,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "STOP_SENDING not valid in " "INITIAL/HANDSHAKE"); @@ -1164,7 +1164,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, /* CRYPTO frames are valid everywhere except in 0RTT packets */ if (pkt_type == QUIC_PKT_TYPE_0RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "CRYPTO frame not valid in 0-RTT"); return 0; @@ -1176,7 +1176,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, /* NEW_TOKEN frames are valid in 1RTT packets */ if (pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "NEW_TOKEN valid only in 1-RTT"); return 0; @@ -1197,7 +1197,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "STREAM valid only in 0/1-RTT"); return 0; @@ -1212,7 +1212,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "MAX_DATA valid only in 0/1-RTT"); return 0; @@ -1225,7 +1225,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "MAX_STREAM_DATA valid only in 0/1-RTT"); return 0; @@ -1240,7 +1240,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "MAX_STREAMS valid only in 0/1-RTT"); return 0; @@ -1255,7 +1255,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "DATA_BLOCKED valid only in 0/1-RTT"); return 0; @@ -1268,7 +1268,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "STREAM_DATA_BLOCKED valid only in 0/1-RTT"); return 0; @@ -1283,7 +1283,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "STREAMS valid only in 0/1-RTT"); return 0; @@ -1298,7 +1298,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "NEW_CONN_ID valid only in 0/1-RTT"); } @@ -1310,7 +1310,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "RETIRE_CONN_ID valid only in 0/1-RTT"); return 0; @@ -1323,7 +1323,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "PATH_CHALLENGE valid only in 0/1-RTT"); return 0; @@ -1336,7 +1336,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, /* PATH_RESPONSE frames are valid in 1RTT packets */ if (pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "PATH_CHALLENGE valid only in 1-RTT"); return 0; @@ -1350,7 +1350,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, if (pkt_type != QUIC_PKT_TYPE_0RTT && pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "CONN_CLOSE (APP) valid only in 0/1-RTT"); return 0; @@ -1366,7 +1366,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, /* HANDSHAKE_DONE frames are valid in 1RTT packets */ if (pkt_type != QUIC_PKT_TYPE_1RTT) { ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_ERR_PROTOCOL_VIOLATION, frame_type, "HANDSHAKE_DONE valid only in 1-RTT"); return 0; @@ -1378,7 +1378,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, default: /* Unknown frame type */ ossl_quic_channel_raise_protocol_error(ch, - QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, frame_type, "Unknown frame type received"); return 0; diff --git a/libs/openssl-3/ssl/quic/quic_srt_gen.c b/libs/openssl-3/ssl/quic/quic_srt_gen.c new file mode 100644 index 000000000..233e4aa62 --- /dev/null +++ b/libs/openssl-3/ssl/quic/quic_srt_gen.c @@ -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 + */ +#include "internal/quic_srt_gen.h" +#include +#include + +struct quic_srt_gen_st { + EVP_MAC *mac; + EVP_MAC_CTX *mac_ctx; +}; + +/* + * Simple HMAC-SHA256-based stateless reset token generator. + */ + +QUIC_SRT_GEN *ossl_quic_srt_gen_new(OSSL_LIB_CTX *libctx, const char *propq, + const unsigned char *key, size_t key_len) +{ + QUIC_SRT_GEN *srt_gen; + OSSL_PARAM params[3], *p = params; + + if ((srt_gen = OPENSSL_zalloc(sizeof(*srt_gen))) == NULL) + return NULL; + + if ((srt_gen->mac = EVP_MAC_fetch(libctx, "HMAC", propq)) == NULL) + goto err; + + if ((srt_gen->mac_ctx = EVP_MAC_CTX_new(srt_gen->mac)) == NULL) + goto err; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "SHA256", 7); + if (propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES, + (char *)propq, 0); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_MAC_init(srt_gen->mac_ctx, key, key_len, params)) + goto err; + + return srt_gen; + +err: + ossl_quic_srt_gen_free(srt_gen); + return NULL; +} + +void ossl_quic_srt_gen_free(QUIC_SRT_GEN *srt_gen) +{ + if (srt_gen == NULL) + return; + + EVP_MAC_CTX_free(srt_gen->mac_ctx); + EVP_MAC_free(srt_gen->mac); + OPENSSL_free(srt_gen); +} + +int ossl_quic_srt_gen_calculate_token(QUIC_SRT_GEN *srt_gen, + const QUIC_CONN_ID *dcid, + QUIC_STATELESS_RESET_TOKEN *token) +{ + size_t outl = 0; + unsigned char mac[SHA256_DIGEST_LENGTH]; + + if (!EVP_MAC_init(srt_gen->mac_ctx, NULL, 0, NULL)) + return 0; + + if (!EVP_MAC_update(srt_gen->mac_ctx, (const unsigned char *)dcid->id, + dcid->id_len)) + return 0; + + if (!EVP_MAC_final(srt_gen->mac_ctx, mac, &outl, sizeof(mac)) + || outl != sizeof(mac)) + return 0; + + assert(sizeof(mac) >= sizeof(token->token)); + memcpy(token->token, mac, sizeof(token->token)); + return 1; +} diff --git a/libs/openssl-3/ssl/quic/quic_srtm.c b/libs/openssl-3/ssl/quic/quic_srtm.c new file mode 100644 index 000000000..3d0bfd97c --- /dev/null +++ b/libs/openssl-3/ssl/quic/quic_srtm.c @@ -0,0 +1,565 @@ +/* + * 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 + */ + +#include "internal/quic_srtm.h" +#include "internal/common.h" +#include +#include +#include + +/* + * QUIC Stateless Reset Token Manager + * ================================== + */ +typedef struct srtm_item_st SRTM_ITEM; + +#define BLINDED_SRT_LEN 16 + +DEFINE_LHASH_OF_EX(SRTM_ITEM); + +/* + * The SRTM is implemented using two LHASH instances, one matching opaque pointers to + * an item structure, and another matching a SRT-derived value to an item + * structure. Multiple items with different seq_num values under a given opaque, + * and duplicate SRTs, are handled using sorted singly-linked lists. + * + * The O(n) insert and lookup performance is tolerated on the basis that the + * total number of entries for a given opaque (total number of extant CIDs for a + * connection) should be quite small, and the QUIC protocol allows us to place a + * hard limit on this via the active_connection_id_limit TPARAM. Thus there is + * no risk of a large number of SRTs needing to be registered under a given + * opaque. + * + * It is expected one SRTM will exist per QUIC_PORT and track all SRTs across + * all connections for that QUIC_PORT. + */ +struct srtm_item_st { + SRTM_ITEM *next_by_srt_blinded; /* SORT BY opaque DESC */ + SRTM_ITEM *next_by_seq_num; /* SORT BY seq_num DESC */ + void *opaque; /* \__ unique identity for item */ + uint64_t seq_num; /* / */ + QUIC_STATELESS_RESET_TOKEN srt; + unsigned char srt_blinded[BLINDED_SRT_LEN]; /* H(srt) */ + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + uint32_t debug_token; +#endif +}; + +struct quic_srtm_st { + /* Crypto context used to calculate blinded SRTs H(srt). */ + EVP_CIPHER_CTX *blind_ctx; /* kept with key */ + + LHASH_OF(SRTM_ITEM) *items_fwd; /* (opaque) -> SRTM_ITEM */ + LHASH_OF(SRTM_ITEM) *items_rev; /* (H(srt)) -> SRTM_ITEM */ + + /* + * Monotonically transitions to 1 in event of allocation failure. The only + * valid operation on such an object is to free it. + */ + unsigned int alloc_failed : 1; +}; + +static unsigned long items_fwd_hash(const SRTM_ITEM *item) +{ + return (unsigned long)(uintptr_t)item->opaque; +} + +static int items_fwd_cmp(const SRTM_ITEM *a, const SRTM_ITEM *b) +{ + return a->opaque != b->opaque; +} + +static unsigned long items_rev_hash(const SRTM_ITEM *item) +{ + /* + * srt_blinded has already been through a crypto-grade hash function, so we + * can just use bits from that. + */ + unsigned long l; + + memcpy(&l, item->srt_blinded, sizeof(l)); + return l; +} + +static int items_rev_cmp(const SRTM_ITEM *a, const SRTM_ITEM *b) +{ + /* + * We don't need to use CRYPTO_memcmp here as the relationship of + * srt_blinded to srt is already cryptographically obfuscated. + */ + return memcmp(a->srt_blinded, b->srt_blinded, sizeof(a->srt_blinded)); +} + +static int srtm_check_lh(QUIC_SRTM *srtm, LHASH_OF(SRTM_ITEM) *lh) +{ + if (lh_SRTM_ITEM_error(lh)) { + srtm->alloc_failed = 1; + return 0; + } + + return 1; +} + +QUIC_SRTM *ossl_quic_srtm_new(OSSL_LIB_CTX *libctx, const char *propq) +{ + QUIC_SRTM *srtm = NULL; + unsigned char key[16]; + EVP_CIPHER *ecb = NULL; + + if (RAND_priv_bytes_ex(libctx, key, sizeof(key), sizeof(key) * 8) != 1) + goto err; + + if ((srtm = OPENSSL_zalloc(sizeof(*srtm))) == NULL) + return NULL; + + /* Use AES-128-ECB as a permutation over 128-bit SRTs. */ + if ((ecb = EVP_CIPHER_fetch(libctx, "AES-128-ECB", propq)) == NULL) + goto err; + + if ((srtm->blind_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + + if (!EVP_EncryptInit_ex2(srtm->blind_ctx, ecb, key, NULL, NULL)) + goto err; + + EVP_CIPHER_free(ecb); + ecb = NULL; + + /* Create mappings. */ + if ((srtm->items_fwd = lh_SRTM_ITEM_new(items_fwd_hash, items_fwd_cmp)) == NULL + || (srtm->items_rev = lh_SRTM_ITEM_new(items_rev_hash, items_rev_cmp)) == NULL) + goto err; + + return srtm; + +err: + /* + * No cleansing of key needed as blinding exists only for side channel + * mitigation. + */ + ossl_quic_srtm_free(srtm); + EVP_CIPHER_free(ecb); + return NULL; +} + +static void srtm_free_each(SRTM_ITEM *ihead) +{ + SRTM_ITEM *inext, *item = ihead; + + for (item = item->next_by_seq_num; item != NULL; item = inext) { + inext = item->next_by_seq_num; + OPENSSL_free(item); + } + + OPENSSL_free(ihead); +} + +void ossl_quic_srtm_free(QUIC_SRTM *srtm) +{ + if (srtm == NULL) + return; + + lh_SRTM_ITEM_free(srtm->items_rev); + if (srtm->items_fwd != NULL) { + lh_SRTM_ITEM_doall(srtm->items_fwd, srtm_free_each); + lh_SRTM_ITEM_free(srtm->items_fwd); + } + + EVP_CIPHER_CTX_free(srtm->blind_ctx); + OPENSSL_free(srtm); +} + +/* + * Find a SRTM_ITEM by (opaque, seq_num). Returns NULL if no match. + * If head is non-NULL, writes the head of the relevant opaque list to *head if + * there is one. + * If prev is non-NULL, writes the previous node to *prev or NULL if it is + * the first item. + */ +static SRTM_ITEM *srtm_find(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num, + SRTM_ITEM **head_p, SRTM_ITEM **prev_p) +{ + SRTM_ITEM key, *item = NULL, *prev = NULL; + + key.opaque = opaque; + + item = lh_SRTM_ITEM_retrieve(srtm->items_fwd, &key); + if (head_p != NULL) + *head_p = item; + + for (; item != NULL; prev = item, item = item->next_by_seq_num) + if (item->seq_num == seq_num) { + break; + } else if (item->seq_num < seq_num) { + /* + * List is sorted in descending order so there can't be any match + * after this. + */ + item = NULL; + break; + } + + if (prev_p != NULL) + *prev_p = prev; + + return item; +} + +/* + * Inserts a SRTM_ITEM into the singly-linked by-sequence-number linked list. + * The new head pointer is written to *new_head (which may or may not be + * unchanged). + */ +static void sorted_insert_seq_num(SRTM_ITEM *head, SRTM_ITEM *item, SRTM_ITEM **new_head) +{ + uint64_t seq_num = item->seq_num; + SRTM_ITEM *cur = head, **fixup = new_head; + + *new_head = head; + + while (cur != NULL && cur->seq_num > seq_num) { + fixup = &cur->next_by_seq_num; + cur = cur->next_by_seq_num; + } + + item->next_by_seq_num = *fixup; + *fixup = item; +} + +/* + * Inserts a SRTM_ITEM into the singly-linked by-SRT list. + * The new head pointer is written to *new_head (which may or may not be + * unchanged). + */ +static void sorted_insert_srt(SRTM_ITEM *head, SRTM_ITEM *item, SRTM_ITEM **new_head) +{ + uintptr_t opaque = (uintptr_t)item->opaque; + SRTM_ITEM *cur = head, **fixup = new_head; + + *new_head = head; + + while (cur != NULL && (uintptr_t)cur->opaque > opaque) { + fixup = &cur->next_by_srt_blinded; + cur = cur->next_by_srt_blinded; + } + + item->next_by_srt_blinded = *fixup; + *fixup = item; +} + +/* + * Computes the blinded SRT value used for internal lookup for side channel + * mitigation purposes. We compute this once as a cached value when an SRTM_ITEM + * is formed. + */ +static int srtm_compute_blinded(QUIC_SRTM *srtm, SRTM_ITEM *item, + const QUIC_STATELESS_RESET_TOKEN *token) +{ + int outl = 0; + + /* + * We use AES-128-ECB as a permutation using a random key to facilitate + * blinding for side-channel purposes. Encrypt the token as a single AES + * block. + */ + if (!EVP_EncryptUpdate(srtm->blind_ctx, item->srt_blinded, &outl, + (const unsigned char *)token, sizeof(*token))) + return 0; + + if (!ossl_assert(outl == sizeof(*token))) + return 0; + + return 1; +} + +int ossl_quic_srtm_add(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num, + const QUIC_STATELESS_RESET_TOKEN *token) +{ + SRTM_ITEM *item = NULL, *head = NULL, *new_head, *r_item; + + if (srtm->alloc_failed) + return 0; + + /* (opaque, seq_num) duplicates not allowed */ + if ((item = srtm_find(srtm, opaque, seq_num, &head, NULL)) != NULL) + return 0; + + if ((item = OPENSSL_zalloc(sizeof(*item))) == NULL) + return 0; + + item->opaque = opaque; + item->seq_num = seq_num; + item->srt = *token; + if (!srtm_compute_blinded(srtm, item, &item->srt)) { + OPENSSL_free(item); + return 0; + } + + /* Add to forward mapping. */ + if (head == NULL) { + /* First item under this opaque */ + lh_SRTM_ITEM_insert(srtm->items_fwd, item); + if (!srtm_check_lh(srtm, srtm->items_fwd)) { + OPENSSL_free(item); + return 0; + } + } else { + sorted_insert_seq_num(head, item, &new_head); + if (new_head != head) { /* head changed, update in lhash */ + lh_SRTM_ITEM_insert(srtm->items_fwd, new_head); + if (!srtm_check_lh(srtm, srtm->items_fwd)) { + OPENSSL_free(item); + return 0; + } + } + } + + /* Add to reverse mapping. */ + r_item = lh_SRTM_ITEM_retrieve(srtm->items_rev, item); + if (r_item == NULL) { + /* First item under this blinded SRT */ + lh_SRTM_ITEM_insert(srtm->items_rev, item); + if (!srtm_check_lh(srtm, srtm->items_rev)) + /* + * Can't free the item now as we would have to undo the insertion + * into the forward mapping which would require an insert operation + * to restore the previous value. which might also fail. However, + * the item will be freed OK when we free the entire SRTM. + */ + return 0; + } else { + sorted_insert_srt(r_item, item, &new_head); + if (new_head != r_item) { /* head changed, update in lhash */ + lh_SRTM_ITEM_insert(srtm->items_rev, new_head); + if (!srtm_check_lh(srtm, srtm->items_rev)) + /* As above. */ + return 0; + } + } + + return 1; +} + +/* Remove item from reverse mapping. */ +static int srtm_remove_from_rev(QUIC_SRTM *srtm, SRTM_ITEM *item) +{ + SRTM_ITEM *rh_item; + + rh_item = lh_SRTM_ITEM_retrieve(srtm->items_rev, item); + assert(rh_item != NULL); + if (rh_item == item) { + /* + * Change lhash to point to item after this one, or remove the entry if + * this is the last one. + */ + if (item->next_by_srt_blinded != NULL) { + lh_SRTM_ITEM_insert(srtm->items_rev, item->next_by_srt_blinded); + if (!srtm_check_lh(srtm, srtm->items_rev)) + return 0; + } else { + lh_SRTM_ITEM_delete(srtm->items_rev, item); + } + } else { + /* Find our entry in the SRT list */ + for (; rh_item->next_by_srt_blinded != item; + rh_item = rh_item->next_by_srt_blinded); + rh_item->next_by_srt_blinded = item->next_by_srt_blinded; + } + + return 1; +} + +int ossl_quic_srtm_remove(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num) +{ + SRTM_ITEM *item, *prev = NULL; + + if (srtm->alloc_failed) + return 0; + + if ((item = srtm_find(srtm, opaque, seq_num, NULL, &prev)) == NULL) + /* No match */ + return 0; + + /* Remove from forward mapping. */ + if (prev == NULL) { + /* + * Change lhash to point to item after this one, or remove the entry if + * this is the last one. + */ + if (item->next_by_seq_num != NULL) { + lh_SRTM_ITEM_insert(srtm->items_fwd, item->next_by_seq_num); + if (!srtm_check_lh(srtm, srtm->items_fwd)) + return 0; + } else { + lh_SRTM_ITEM_delete(srtm->items_fwd, item); + } + } else { + prev->next_by_seq_num = item->next_by_seq_num; + } + + /* Remove from reverse mapping. */ + if (!srtm_remove_from_rev(srtm, item)) + return 0; + + OPENSSL_free(item); + return 1; +} + +int ossl_quic_srtm_cull(QUIC_SRTM *srtm, void *opaque) +{ + SRTM_ITEM key, *item = NULL, *inext, *ihead; + + key.opaque = opaque; + + if (srtm->alloc_failed) + return 0; + + if ((ihead = lh_SRTM_ITEM_retrieve(srtm->items_fwd, &key)) == NULL) + return 1; /* nothing removed is a success condition */ + + for (item = ihead; item != NULL; item = inext) { + inext = item->next_by_seq_num; + if (item != ihead) { + srtm_remove_from_rev(srtm, item); + OPENSSL_free(item); + } + } + + lh_SRTM_ITEM_delete(srtm->items_fwd, ihead); + srtm_remove_from_rev(srtm, ihead); + OPENSSL_free(ihead); + return 1; +} + +int ossl_quic_srtm_lookup(QUIC_SRTM *srtm, + const QUIC_STATELESS_RESET_TOKEN *token, + size_t idx, + void **opaque, uint64_t *seq_num) +{ + SRTM_ITEM key, *item; + + if (srtm->alloc_failed) + return 0; + + if (!srtm_compute_blinded(srtm, &key, token)) + return 0; + + item = lh_SRTM_ITEM_retrieve(srtm->items_rev, &key); + for (; idx > 0 && item != NULL; --idx, item = item->next_by_srt_blinded); + if (item == NULL) + return 0; + + if (opaque != NULL) + *opaque = item->opaque; + if (seq_num != NULL) + *seq_num = item->seq_num; + + return 1; +} + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + +static uint32_t token_next = 0x5eadbeef; +static size_t tokens_seen; + +struct check_args { + uint32_t token; + int mode; +}; + +static void check_mark(SRTM_ITEM *item, void *arg) +{ + struct check_args *arg_ = arg; + uint32_t token = arg_->token; + uint64_t prev_seq_num = 0; + void *prev_opaque = NULL; + int have_prev = 0; + + assert(item != NULL); + + while (item != NULL) { + if (have_prev) { + assert(!(item->opaque == prev_opaque && item->seq_num == prev_seq_num)); + if (!arg_->mode) + assert(item->opaque != prev_opaque || item->seq_num < prev_seq_num); + } + + ++tokens_seen; + item->debug_token = token; + prev_opaque = item->opaque; + prev_seq_num = item->seq_num; + have_prev = 1; + + if (arg_->mode) + item = item->next_by_srt_blinded; + else + item = item->next_by_seq_num; + } +} + +static void check_count(SRTM_ITEM *item, void *arg) +{ + struct check_args *arg_ = arg; + uint32_t token = arg_->token; + + assert(item != NULL); + + while (item != NULL) { + ++tokens_seen; + assert(item->debug_token == token); + + if (arg_->mode) + item = item->next_by_seq_num; + else + item = item->next_by_srt_blinded; + } +} + +#endif + +void ossl_quic_srtm_check(const QUIC_SRTM *srtm) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + struct check_args args = {0}; + size_t tokens_expected, tokens_expected_old; + + args.token = token_next; + ++token_next; + + assert(srtm != NULL); + assert(srtm->blind_ctx != NULL); + assert(srtm->items_fwd != NULL); + assert(srtm->items_rev != NULL); + + tokens_seen = 0; + lh_SRTM_ITEM_doall_arg(srtm->items_fwd, check_mark, &args); + + tokens_expected = tokens_seen; + tokens_seen = 0; + lh_SRTM_ITEM_doall_arg(srtm->items_rev, check_count, &args); + + assert(tokens_seen == tokens_expected); + tokens_expected_old = tokens_expected; + + args.token = token_next; + ++token_next; + + args.mode = 1; + tokens_seen = 0; + lh_SRTM_ITEM_doall_arg(srtm->items_rev, check_mark, &args); + + tokens_expected = tokens_seen; + tokens_seen = 0; + lh_SRTM_ITEM_doall_arg(srtm->items_fwd, check_count, &args); + + assert(tokens_seen == tokens_expected); + assert(tokens_seen == tokens_expected_old); +#endif +} diff --git a/libs/openssl-3/ssl/quic/quic_stream_map.c b/libs/openssl-3/ssl/quic/quic_stream_map.c index f8278c991..c836721f7 100644 --- a/libs/openssl-3/ssl/quic/quic_stream_map.c +++ b/libs/openssl-3/ssl/quic/quic_stream_map.c @@ -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 @@ -103,7 +103,8 @@ int ossl_quic_stream_map_init(QUIC_STREAM_MAP *qsm, qsm->rr_counter = 0; qsm->rr_cur = NULL; - qsm->num_accept = 0; + qsm->num_accept_bidi = 0; + qsm->num_accept_uni = 0; qsm->num_shutdown_flush = 0; qsm->get_stream_limit_cb = get_stream_limit_cb; @@ -737,7 +738,10 @@ void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) { list_insert_tail(&qsm->accept_list, &s->accept_node); - ++qsm->num_accept; + if (ossl_quic_stream_is_bidi(s)) + ++qsm->num_accept_bidi; + else + ++qsm->num_accept_uni; } static QUIC_RXFC *qsm_get_max_streams_rxfc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) @@ -754,15 +758,24 @@ void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm, QUIC_RXFC *max_streams_rxfc; list_remove(&qsm->accept_list, &s->accept_node); - --qsm->num_accept; + if (ossl_quic_stream_is_bidi(s)) + --qsm->num_accept_bidi; + else + --qsm->num_accept_uni; if ((max_streams_rxfc = qsm_get_max_streams_rxfc(qsm, s)) != NULL) ossl_quic_rxfc_on_retire(max_streams_rxfc, 1, rtt); } -size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm) +size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm, int is_uni) +{ + return is_uni ? qsm->num_accept_uni : qsm->num_accept_bidi; +} + +size_t ossl_quic_stream_map_get_total_accept_queue_len(QUIC_STREAM_MAP *qsm) { - return qsm->num_accept; + return ossl_quic_stream_map_get_accept_queue_len(qsm, /*is_uni=*/0) + + ossl_quic_stream_map_get_accept_queue_len(qsm, /*is_uni=*/1); } void ossl_quic_stream_map_gc(QUIC_STREAM_MAP *qsm) diff --git a/libs/openssl-3/ssl/quic/quic_thread_assist.c b/libs/openssl-3/ssl/quic/quic_thread_assist.c index e1de72a91..26c738cb5 100644 --- a/libs/openssl-3/ssl/quic/quic_thread_assist.c +++ b/libs/openssl-3/ssl/quic/quic_thread_assist.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * 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 @@ -91,7 +91,7 @@ int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta, qta->t = ossl_crypto_thread_native_start(assist_thread_main, qta, /*joinable=*/1); if (qta->t == NULL) { - ossl_crypto_condvar_free(qta->cv); + ossl_crypto_condvar_free(&qta->cv); return 0; } diff --git a/libs/openssl-3/ssl/quic/quic_tls.c b/libs/openssl-3/ssl/quic/quic_tls.c index 25687db2f..bd560c9a9 100644 --- a/libs/openssl-3/ssl/quic/quic_tls.c +++ b/libs/openssl-3/ssl/quic/quic_tls.c @@ -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 @@ -696,7 +696,7 @@ static int raise_error(QUIC_TLS *qtls, uint64_t error_code, OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC) #define RAISE_INTERNAL_ERROR(qtls) \ - RAISE_ERROR((qtls), QUIC_ERR_INTERNAL_ERROR, "internal error") + RAISE_ERROR((qtls), OSSL_QUIC_ERR_INTERNAL_ERROR, "internal error") int ossl_quic_tls_tick(QUIC_TLS *qtls) { @@ -746,7 +746,7 @@ int ossl_quic_tls_tick(QUIC_TLS *qtls) return RAISE_INTERNAL_ERROR(qtls); } else { if (sc->ext.alpn == NULL || sc->ext.alpn_len == 0) - return RAISE_ERROR(qtls, QUIC_ERR_CRYPTO_NO_APP_PROTO, + return RAISE_ERROR(qtls, OSSL_QUIC_ERR_CRYPTO_NO_APP_PROTO, "ALPN must be configured when using QUIC"); } if (!SSL_set_min_proto_version(qtls->args.s, TLS1_3_VERSION)) @@ -816,7 +816,7 @@ int ossl_quic_tls_tick(QUIC_TLS *qtls) /* Validate that we have ALPN */ SSL_get0_alpn_selected(qtls->args.s, &alpn, &alpnlen); if (alpn == NULL || alpnlen == 0) - return RAISE_ERROR(qtls, QUIC_ERR_CRYPTO_NO_APP_PROTO, + return RAISE_ERROR(qtls, OSSL_QUIC_ERR_CRYPTO_NO_APP_PROTO, "no application protocol negotiated"); qtls->complete = 1; diff --git a/libs/openssl-3/ssl/quic/quic_tserver.c b/libs/openssl-3/ssl/quic/quic_tserver.c index 3fc51b4a7..b9de60aea 100644 --- a/libs/openssl-3/ssl/quic/quic_tserver.c +++ b/libs/openssl-3/ssl/quic/quic_tserver.c @@ -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 @@ -10,6 +10,8 @@ #include "internal/quic_tserver.h" #include "internal/quic_channel.h" #include "internal/quic_statm.h" +#include "internal/quic_port.h" +#include "internal/quic_engine.h" #include "internal/common.h" #include "internal/time.h" #include "quic_local.h" @@ -25,8 +27,11 @@ struct quic_tserver_st { SSL *ssl; /* - * The QUIC channel providing the core QUIC connection implementation. + * The QUIC engine, port and channel providing the core QUIC connection + * implementation. */ + QUIC_ENGINE *engine; + QUIC_PORT *port; QUIC_CHANNEL *ch; /* The mutex we give to the QUIC channel. */ @@ -53,7 +58,7 @@ static int alpn_select_cb(SSL *ssl, const unsigned char **out, static const unsigned char alpndeflt[] = { 8, 'o', 's', 's', 'l', 't', 'e', 's', 't' }; - static const unsigned char *alpn; + const unsigned char *alpn; size_t alpnlen; if (srv->args.alpn == NULL) { @@ -75,7 +80,8 @@ QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args, const char *certfile, const char *keyfile) { QUIC_TSERVER *srv = NULL; - QUIC_CHANNEL_ARGS ch_args = {0}; + QUIC_ENGINE_ARGS engine_args = {0}; + QUIC_PORT_ARGS port_args = {0}; QUIC_CONNECTION *qc = NULL; if (args->net_rbio == NULL || args->net_wbio == NULL) @@ -113,19 +119,26 @@ QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args, if (srv->tls == NULL) goto err; - ch_args.libctx = srv->args.libctx; - ch_args.propq = srv->args.propq; - ch_args.tls = srv->tls; - ch_args.mutex = srv->mutex; - ch_args.is_server = 1; - ch_args.now_cb = srv->args.now_cb; - ch_args.now_cb_arg = srv->args.now_cb_arg; + engine_args.libctx = srv->args.libctx; + engine_args.propq = srv->args.propq; + engine_args.mutex = srv->mutex; + engine_args.now_cb = srv->args.now_cb; + engine_args.now_cb_arg = srv->args.now_cb_arg; - if ((srv->ch = ossl_quic_channel_new(&ch_args)) == NULL) + if ((srv->engine = ossl_quic_engine_new(&engine_args)) == NULL) goto err; - if (!ossl_quic_channel_set_net_rbio(srv->ch, srv->args.net_rbio) - || !ossl_quic_channel_set_net_wbio(srv->ch, srv->args.net_wbio)) + port_args.channel_ctx = srv->ctx; + port_args.is_multi_conn = 1; + + if ((srv->port = ossl_quic_engine_create_port(srv->engine, &port_args)) == NULL) + goto err; + + if ((srv->ch = ossl_quic_port_create_incoming(srv->port, srv->tls)) == NULL) + goto err; + + if (!ossl_quic_port_set_net_rbio(srv->port, srv->args.net_rbio) + || !ossl_quic_port_set_net_wbio(srv->port, srv->args.net_wbio)) goto err; qc = OPENSSL_zalloc(sizeof(*qc)); @@ -143,6 +156,8 @@ QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args, SSL_CTX_free(srv->ctx); SSL_free(srv->tls); ossl_quic_channel_free(srv->ch); + ossl_quic_port_free(srv->port); + ossl_quic_engine_free(srv->engine); #if defined(OPENSSL_THREADS) ossl_crypto_mutex_free(&srv->mutex); #endif @@ -158,11 +173,13 @@ void ossl_quic_tserver_free(QUIC_TSERVER *srv) if (srv == NULL) return; + SSL_free(srv->tls); ossl_quic_channel_free(srv->ch); + ossl_quic_port_free(srv->port); + ossl_quic_engine_free(srv->engine); BIO_free_all(srv->args.net_rbio); BIO_free_all(srv->args.net_wbio); OPENSSL_free(srv->ssl); - SSL_free(srv->tls); SSL_CTX_free(srv->ctx); #if defined(OPENSSL_THREADS) ossl_crypto_mutex_free(&srv->mutex); diff --git a/libs/openssl-3/ssl/quic/quic_txp.c b/libs/openssl-3/ssl/quic/quic_txp.c index f26f1e81a..2532d1edc 100644 --- a/libs/openssl-3/ssl/quic/quic_txp.c +++ b/libs/openssl-3/ssl/quic/quic_txp.c @@ -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 @@ -481,7 +481,9 @@ OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETIS get_sstream_by_id, txp, on_regen_notify, txp, on_confirm_notify, txp, - on_sstream_updated, txp)) { + on_sstream_updated, txp, + args->get_qlog_cb, + args->get_qlog_cb_arg)) { OPENSSL_free(txp); return NULL; } @@ -625,6 +627,14 @@ void ossl_quic_tx_packetiser_set_ack_tx_cb(OSSL_QUIC_TX_PACKETISER *txp, txp->ack_tx_cb_arg = cb_arg; } +void ossl_quic_tx_packetiser_set_qlog_cb(OSSL_QUIC_TX_PACKETISER *txp, + QLOG *(*get_qlog_cb)(void *arg), + void *get_qlog_cb_arg) +{ + ossl_quic_fifd_set_qlog_cb(&txp->fifd, get_qlog_cb, get_qlog_cb_arg); + +} + int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level) { @@ -1590,10 +1600,21 @@ static void on_regen_notify(uint64_t frame_type, uint64_t stream_id, } } +static int txp_need_ping(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t pn_space, + const struct archetype_data *adata) +{ + return adata->allow_ping + && (adata->require_ack_eliciting + || (txp->force_ack_eliciting & (1UL << pn_space)) != 0); +} + static int txp_pkt_init(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level, uint32_t archetype, size_t running_total) { + uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + if (!txp_determine_geometry(txp, archetype, enc_level, running_total, &pkt->phdr, &pkt->geom)) return 0; @@ -1604,7 +1625,7 @@ static int txp_pkt_init(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp, */ if (!tx_helper_init(&pkt->h, txp, enc_level, pkt->geom.cmppl, - pkt->geom.adata.require_ack_eliciting ? 1 : 0)) + txp_need_ping(txp, pn_space, &pkt->geom.adata) ? 1 : 0)) return 0; pkt->h_valid = 1; @@ -1872,7 +1893,7 @@ static int txp_generate_pre_token(OSSL_QUIC_TX_PACKETISER *txp, pf = &f; pf->is_app = 0; pf->frame_type = 0; - pf->error_code = QUIC_ERR_APPLICATION_ERROR; + pf->error_code = OSSL_QUIC_ERR_APPLICATION_ERROR; pf->reason = NULL; pf->reason_len = 0; } @@ -2772,11 +2793,10 @@ static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, /* PING */ tx_helper_unrestrict(h); - if ((a.require_ack_eliciting - || (txp->force_ack_eliciting & (1UL << pn_space)) != 0) - && !have_ack_eliciting && a.allow_ping) { + if (!have_ack_eliciting && txp_need_ping(txp, pn_space, &a)) { WPACKET *wpkt; + assert(h->reserve > 0); wpkt = tx_helper_begin(h); if (wpkt == NULL) goto fatal_err; @@ -2811,6 +2831,7 @@ static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, tpkt->ackm_pkt.is_pto_probe = 0; tpkt->ackm_pkt.is_mtu_probe = 0; tpkt->ackm_pkt.time = txp->args.now(txp->args.now_arg); + tpkt->pkt_type = pkt->phdr.type; /* Done. */ return rc; diff --git a/libs/openssl-3/ssl/quic/quic_types.c b/libs/openssl-3/ssl/quic/quic_types.c new file mode 100644 index 000000000..4ff3ae658 --- /dev/null +++ b/libs/openssl-3/ssl/quic/quic_types.c @@ -0,0 +1,29 @@ +/* + * 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 + */ + +#include "internal/quic_types.h" +#include +#include + +int ossl_quic_gen_rand_conn_id(OSSL_LIB_CTX *libctx, size_t len, + QUIC_CONN_ID *cid) +{ + if (len > QUIC_MAX_CONN_ID_LEN) + return 0; + + cid->id_len = (unsigned char)len; + + if (RAND_bytes_ex(libctx, cid->id, len, len * 8) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_RAND_LIB); + cid->id_len = 0; + return 0; + } + + return 1; +} diff --git a/libs/openssl-3/ssl/quic/quic_wire.c b/libs/openssl-3/ssl/quic/quic_wire.c index 425e7efc2..a7c766779 100644 --- a/libs/openssl-3/ssl/quic/quic_wire.c +++ b/libs/openssl-3/ssl/quic/quic_wire.c @@ -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 @@ -1053,7 +1053,7 @@ ossl_quic_frame_type_to_string(uint64_t frame_type) const char *ossl_quic_err_to_string(uint64_t error_code) { switch (error_code) { -#define X(name) case QUIC_ERR_##name: return #name; +#define X(name) case OSSL_QUIC_ERR_##name: return #name; X(NO_ERROR) X(INTERNAL_ERROR) X(CONNECTION_REFUSED) diff --git a/libs/openssl-3/ssl/record/methods/dtls_meth.c b/libs/openssl-3/ssl/record/methods/dtls_meth.c index 258dbd3b1..a5e6c8234 100644 --- a/libs/openssl-3/ssl/record/methods/dtls_meth.c +++ b/libs/openssl-3/ssl/record/methods/dtls_meth.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. * * 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 @@ -90,11 +90,9 @@ static DTLS_BITMAP *dtls_get_bitmap(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rr, return &rl->bitmap; /* - * We can only handle messages from the next epoch if we have already - * processed all of the unprocessed records from the previous epoch + * Check if the message is from the next epoch */ - else if (rr->epoch == (unsigned long)(rl->epoch + 1) - && rl->unprocessed_rcds.epoch != rl->epoch) { + else if (rr->epoch == rl->epoch + 1) { *is_next_epoch = 1; return &rl->next_bitmap; } @@ -280,14 +278,14 @@ static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) return ret; } -static int dtls_rlayer_buffer_record(OSSL_RECORD_LAYER *rl, record_pqueue *queue, +static int dtls_rlayer_buffer_record(OSSL_RECORD_LAYER *rl, struct pqueue_st *queue, unsigned char *priority) { DTLS_RLAYER_RECORD_DATA *rdata; pitem *item; /* Limit the size of the queue to prevent DOS attacks */ - if (pqueue_size(queue->q) >= 100) + if (pqueue_size(queue) >= 100) return 0; rdata = OPENSSL_malloc(sizeof(*rdata)); @@ -319,7 +317,7 @@ static int dtls_rlayer_buffer_record(OSSL_RECORD_LAYER *rl, record_pqueue *queue return -1; } - if (pqueue_insert(queue->q, item) == NULL) { + if (pqueue_insert(queue, item) == NULL) { /* Must be a duplicate so ignore it */ OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(rdata); @@ -350,11 +348,11 @@ static int dtls_copy_rlayer_record(OSSL_RECORD_LAYER *rl, pitem *item) } static int dtls_retrieve_rlayer_buffered_record(OSSL_RECORD_LAYER *rl, - record_pqueue *queue) + struct pqueue_st *queue) { pitem *item; - item = pqueue_pop(queue->q); + item = pqueue_pop(queue); if (item) { dtls_copy_rlayer_record(rl, item); @@ -401,7 +399,7 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl) again: /* if we're renegotiating, then there may be buffered records */ - if (dtls_retrieve_rlayer_buffered_record(rl, &rl->processed_rcds)) { + if (dtls_retrieve_rlayer_buffered_record(rl, rl->processed_rcds)) { rl->num_recs = 1; return OSSL_RECORD_RETURN_SUCCESS; } @@ -547,7 +545,7 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl) */ if (is_next_epoch) { if (rl->in_init) { - if (dtls_rlayer_buffer_record(rl, &(rl->unprocessed_rcds), + if (dtls_rlayer_buffer_record(rl, rl->unprocessed_rcds, rr->seq_num) < 0) { /* RLAYERfatal() already called */ return OSSL_RECORD_RETURN_FATAL; @@ -597,8 +595,8 @@ static int dtls_free(OSSL_RECORD_LAYER *rl) rbuf->left = 0; } - if (rl->unprocessed_rcds.q != NULL) { - while ((item = pqueue_pop(rl->unprocessed_rcds.q)) != NULL) { + if (rl->unprocessed_rcds != NULL) { + while ((item = pqueue_pop(rl->unprocessed_rcds)) != NULL) { rdata = (DTLS_RLAYER_RECORD_DATA *)item->data; /* Push to the next record layer */ ret &= BIO_write_ex(rl->next, rdata->packet, rdata->packet_length, @@ -607,17 +605,17 @@ static int dtls_free(OSSL_RECORD_LAYER *rl) OPENSSL_free(item->data); pitem_free(item); } - pqueue_free(rl->unprocessed_rcds.q); + pqueue_free(rl->unprocessed_rcds); } - if (rl->processed_rcds.q != NULL) { - while ((item = pqueue_pop(rl->processed_rcds.q)) != NULL) { + if (rl->processed_rcds!= NULL) { + while ((item = pqueue_pop(rl->processed_rcds)) != NULL) { rdata = (DTLS_RLAYER_RECORD_DATA *)item->data; OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(item->data); pitem_free(item); } - pqueue_free(rl->processed_rcds.q); + pqueue_free(rl->processed_rcds); } return tls_free(rl) && ret; @@ -641,27 +639,24 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, int ret; ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level, - key, keylen, iv, ivlen, mackey, mackeylen, - ciph, taglen, mactype, md, comp, prev, - transport, next, local, peer, settings, + ciph, taglen, md, comp, prev, + transport, next, settings, options, fns, cbarg, retrl); if (ret != OSSL_RECORD_RETURN_SUCCESS) return ret; - (*retrl)->unprocessed_rcds.q = pqueue_new(); - (*retrl)->processed_rcds.q = pqueue_new(); - if ((*retrl)->unprocessed_rcds.q == NULL - || (*retrl)->processed_rcds.q == NULL) { + (*retrl)->unprocessed_rcds = pqueue_new(); + (*retrl)->processed_rcds = pqueue_new(); + + if ((*retrl)->unprocessed_rcds == NULL + || (*retrl)->processed_rcds == NULL) { dtls_free(*retrl); *retrl = NULL; ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); return OSSL_RECORD_RETURN_FATAL; } - (*retrl)->unprocessed_rcds.epoch = epoch + 1; - (*retrl)->processed_rcds.epoch = epoch; - (*retrl)->isdtls = 1; (*retrl)->epoch = epoch; (*retrl)->in_init = 1; diff --git a/libs/openssl-3/ssl/record/methods/ktls_meth.c b/libs/openssl-3/ssl/record/methods/ktls_meth.c index af91455c2..33c7140e1 100644 --- a/libs/openssl-3/ssl/record/methods/ktls_meth.c +++ b/libs/openssl-3/ssl/record/methods/ktls_meth.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. * * 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 @@ -417,9 +417,8 @@ ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, int ret; ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level, - key, keylen, iv, ivlen, mackey, mackeylen, - ciph, taglen, mactype, md, comp, prev, - transport, next, local, peer, settings, + ciph, taglen, md, comp, prev, + transport, next, settings, options, fns, cbarg, retrl); if (ret != OSSL_RECORD_RETURN_SUCCESS) diff --git a/libs/openssl-3/ssl/record/methods/recmethod_local.h b/libs/openssl-3/ssl/record/methods/recmethod_local.h index 300b146a7..fe9dce153 100644 --- a/libs/openssl-3/ssl/record/methods/recmethod_local.h +++ b/libs/openssl-3/ssl/record/methods/recmethod_local.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 @@ -344,8 +344,8 @@ struct ossl_record_layer_st size_t taglen; /* DTLS received handshake records (processed and unprocessed) */ - record_pqueue unprocessed_rcds; - record_pqueue processed_rcds; + struct pqueue_st *unprocessed_rcds; + struct pqueue_st *processed_rcds; /* records being received in the current epoch */ DTLS_BITMAP bitmap; @@ -367,7 +367,7 @@ struct ossl_record_layer_st size_t max_pipelines; /* Function pointers for version specific functions */ - struct record_functions_st *funcs; + const struct record_functions_st *funcs; }; typedef struct dtls_rlayer_record_data_st { @@ -377,12 +377,12 @@ typedef struct dtls_rlayer_record_data_st { TLS_RL_RECORD rrec; } DTLS_RLAYER_RECORD_DATA; -extern struct record_functions_st ssl_3_0_funcs; -extern struct record_functions_st tls_1_funcs; -extern struct record_functions_st tls_1_3_funcs; -extern struct record_functions_st tls_any_funcs; -extern struct record_functions_st dtls_1_funcs; -extern struct record_functions_st dtls_any_funcs; +extern const struct record_functions_st ssl_3_0_funcs; +extern const struct record_functions_st tls_1_funcs; +extern const struct record_functions_st tls_1_3_funcs; +extern const struct record_functions_st tls_any_funcs; +extern const struct record_functions_st dtls_1_funcs; +extern const struct record_functions_st dtls_any_funcs; void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason, const char *fmt, ...); @@ -395,7 +395,9 @@ void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason, #define RLAYER_USE_EXPLICIT_IV(rl) ((rl)->version == TLS1_1_VERSION \ || (rl)->version == TLS1_2_VERSION \ - || (rl)->isdtls) + || (rl)->version == DTLS1_BAD_VER \ + || (rl)->version == DTLS1_VERSION \ + || (rl)->version == DTLS1_2_VERSION) void ossl_tls_rl_record_set_seq_num(TLS_RL_RECORD *r, const unsigned char *seq_num); @@ -434,14 +436,10 @@ int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec); int tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, - int role, int direction, int level, unsigned char *key, - size_t keylen, unsigned char *iv, size_t ivlen, - unsigned char *mackey, size_t mackeylen, + int role, int direction, int level, const EVP_CIPHER *ciph, size_t taglen, - int mactype, const EVP_MD *md, COMP_METHOD *comp, BIO *prev, BIO *transport, BIO *next, - BIO_ADDR *local, BIO_ADDR *peer, const OSSL_PARAM *settings, const OSSL_PARAM *options, const OSSL_DISPATCH *fns, void *cbarg, OSSL_RECORD_LAYER **retrl); diff --git a/libs/openssl-3/ssl/record/methods/ssl3_meth.c b/libs/openssl-3/ssl/record/methods/ssl3_meth.c index 810dc0716..6b5a1bed2 100644 --- a/libs/openssl-3/ssl/record/methods/ssl3_meth.c +++ b/libs/openssl-3/ssl/record/methods/ssl3_meth.c @@ -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 @@ -119,6 +119,9 @@ static int ssl3_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *inrecs, l = rec->length; bs = EVP_CIPHER_CTX_get_block_size(ds); + if (bs == 0) + return 0; + /* COMPRESS */ if ((bs != 1) && sending && !provided) { @@ -308,7 +311,7 @@ static int ssl3_mac(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, unsigned char *md return 1; } -struct record_functions_st ssl_3_0_funcs = { +const struct record_functions_st ssl_3_0_funcs = { ssl3_set_crypto_state, ssl3_cipher, ssl3_mac, diff --git a/libs/openssl-3/ssl/record/methods/tls13_meth.c b/libs/openssl-3/ssl/record/methods/tls13_meth.c index ec22f1ee4..d782c327e 100644 --- a/libs/openssl-3/ssl/record/methods/tls13_meth.c +++ b/libs/openssl-3/ssl/record/methods/tls13_meth.c @@ -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 @@ -303,7 +303,7 @@ static int tls13_add_record_padding(OSSL_RECORD_LAYER *rl, return 1; } -struct record_functions_st tls_1_3_funcs = { +const struct record_functions_st tls_1_3_funcs = { tls13_set_crypto_state, tls13_cipher, NULL, diff --git a/libs/openssl-3/ssl/record/methods/tls1_meth.c b/libs/openssl-3/ssl/record/methods/tls1_meth.c index f13d530a0..9275e19fb 100644 --- a/libs/openssl-3/ssl/record/methods/tls1_meth.c +++ b/libs/openssl-3/ssl/record/methods/tls1_meth.c @@ -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,6 +229,11 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, bs = EVP_CIPHER_get_block_size(EVP_CIPHER_CTX_get0_cipher(ds)); + if (bs == 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_CIPHER); + return 0; + } + if (n_recs > 1) { if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) & EVP_CIPH_FLAG_PIPELINE) == 0) { @@ -646,7 +651,7 @@ int tls1_initialise_write_packets(OSSL_RECORD_LAYER *rl, } /* TLSv1.0, TLSv1.1 and TLSv1.2 all use the same funcs */ -struct record_functions_st tls_1_funcs = { +const struct record_functions_st tls_1_funcs = { tls1_set_crypto_state, tls1_cipher, tls1_mac, @@ -667,7 +672,7 @@ struct record_functions_st tls_1_funcs = { NULL }; -struct record_functions_st dtls_1_funcs = { +const struct record_functions_st dtls_1_funcs = { tls1_set_crypto_state, tls1_cipher, tls1_mac, diff --git a/libs/openssl-3/ssl/record/methods/tls_common.c b/libs/openssl-3/ssl/record/methods/tls_common.c index 4cc432ee5..6cb8e8870 100644 --- a/libs/openssl-3/ssl/record/methods/tls_common.c +++ b/libs/openssl-3/ssl/record/methods/tls_common.c @@ -1240,14 +1240,10 @@ int tls_set_options(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options) int tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, - int role, int direction, int level, unsigned char *key, - size_t keylen, unsigned char *iv, size_t ivlen, - unsigned char *mackey, size_t mackeylen, + int role, int direction, int level, const EVP_CIPHER *ciph, size_t taglen, - int mactype, const EVP_MD *md, COMP_METHOD *comp, BIO *prev, - BIO *transport, BIO *next, BIO_ADDR *local, - BIO_ADDR *peer, const OSSL_PARAM *settings, + BIO *transport, BIO *next, const OSSL_PARAM *settings, const OSSL_PARAM *options, const OSSL_DISPATCH *fns, void *cbarg, OSSL_RECORD_LAYER **retrl) @@ -1395,9 +1391,8 @@ tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, int ret; ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level, - key, keylen, iv, ivlen, mackey, mackeylen, - ciph, taglen, mactype, md, comp, prev, - transport, next, local, peer, settings, + ciph, taglen, md, comp, prev, + transport, next, settings, options, fns, cbarg, retrl); if (ret != OSSL_RECORD_RETURN_SUCCESS) diff --git a/libs/openssl-3/ssl/record/methods/tlsany_meth.c b/libs/openssl-3/ssl/record/methods/tlsany_meth.c index 42bbbee8a..3f73f9ebd 100644 --- a/libs/openssl-3/ssl/record/methods/tlsany_meth.c +++ b/libs/openssl-3/ssl/record/methods/tlsany_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 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 @@ -145,7 +145,7 @@ static int tls_any_prepare_for_encryption(OSSL_RECORD_LAYER *rl, return 1; } -struct record_functions_st tls_any_funcs = { +const struct record_functions_st tls_any_funcs = { tls_any_set_crypto_state, tls_any_cipher, NULL, @@ -175,7 +175,7 @@ static int dtls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers) return 1; } -struct record_functions_st dtls_any_funcs = { +const struct record_functions_st dtls_any_funcs = { tls_any_set_crypto_state, tls_any_cipher, NULL, diff --git a/libs/openssl-3/ssl/record/rec_layer_d1.c b/libs/openssl-3/ssl/record/rec_layer_d1.c index 87b588b84..ee45f8117 100644 --- a/libs/openssl-3/ssl/record/rec_layer_d1.c +++ b/libs/openssl-3/ssl/record/rec_layer_d1.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-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 @@ -25,9 +25,9 @@ int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl) rl->d = d; - d->buffered_app_data.q = pqueue_new(); + d->buffered_app_data = pqueue_new(); - if (d->buffered_app_data.q == NULL) { + if (d->buffered_app_data == NULL) { OPENSSL_free(d); rl->d = NULL; return 0; @@ -42,7 +42,7 @@ void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl) return; DTLS_RECORD_LAYER_clear(rl); - pqueue_free(rl->d->buffered_app_data.q); + pqueue_free(rl->d->buffered_app_data); OPENSSL_free(rl->d); rl->d = NULL; } @@ -56,7 +56,7 @@ void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl) d = rl->d; - while ((item = pqueue_pop(d->buffered_app_data.q)) != NULL) { + while ((item = pqueue_pop(d->buffered_app_data)) != NULL) { rec = (TLS_RECORD *)item->data; if (rl->s->options & SSL_OP_CLEANSE_PLAINTEXT) @@ -66,19 +66,19 @@ void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl) pitem_free(item); } - buffered_app_data = d->buffered_app_data.q; + buffered_app_data = d->buffered_app_data; memset(d, 0, sizeof(*d)); - d->buffered_app_data.q = buffered_app_data; + d->buffered_app_data = buffered_app_data; } static int dtls_buffer_record(SSL_CONNECTION *s, TLS_RECORD *rec) { TLS_RECORD *rdata; pitem *item; - record_pqueue *queue = &(s->rlayer.d->buffered_app_data); + struct pqueue_st *queue = s->rlayer.d->buffered_app_data; /* Limit the size of the queue to prevent DOS attacks */ - if (pqueue_size(queue->q) >= 100) + if (pqueue_size(queue) >= 100) return 0; /* We don't buffer partially read records */ @@ -125,7 +125,7 @@ static int dtls_buffer_record(SSL_CONNECTION *s, TLS_RECORD *rec) } #endif - if (pqueue_insert(queue->q, item) == NULL) { + if (pqueue_insert(queue, item) == NULL) { /* Must be a duplicate so ignore it */ OPENSSL_free(rdata->allocdata); OPENSSL_free(rdata); @@ -145,7 +145,7 @@ static void dtls_unbuffer_record(SSL_CONNECTION *s) if (s->rlayer.curr_rec < s->rlayer.num_recs) return; - item = pqueue_pop(s->rlayer.d->buffered_app_data.q); + item = pqueue_pop(s->rlayer.d->buffered_app_data); if (item != NULL) { rdata = (TLS_RECORD *)item->data; @@ -679,3 +679,14 @@ void dtls1_increment_epoch(SSL_CONNECTION *s, int rw) s->rlayer.d->w_epoch++; } } + +uint16_t dtls1_get_epoch(SSL_CONNECTION *s, int rw) { + uint16_t epoch; + + if (rw & SSL3_CC_READ) + epoch = s->rlayer.d->r_epoch; + else + epoch = s->rlayer.d->w_epoch; + + return epoch; +} diff --git a/libs/openssl-3/ssl/record/rec_layer_s3.c b/libs/openssl-3/ssl/record/rec_layer_s3.c index 2fa841e8a..6a31efe1c 100644 --- a/libs/openssl-3/ssl/record/rec_layer_s3.c +++ b/libs/openssl-3/ssl/record/rec_layer_s3.c @@ -41,7 +41,6 @@ int RECORD_LAYER_clear(RECORD_LAYER *rl) rl->handshake_fragment_len = 0; rl->wpend_tot = 0; rl->wpend_type = 0; - rl->wpend_ret = 0; rl->wpend_buf = NULL; rl->alert_count = 0; rl->num_recs = 0; @@ -180,7 +179,7 @@ size_t ssl3_pending(const SSL *s) TLS_RECORD *rdata; pitem *item, *iter; - iter = pqueue_iterator(sc->rlayer.d->buffered_app_data.q); + iter = pqueue_iterator(sc->rlayer.d->buffered_app_data); while ((item = pqueue_next(&iter)) != NULL) { rdata = item->data; num += rdata->length; @@ -354,7 +353,6 @@ int ssl3_write_bytes(SSL *ssl, uint8_t type, const void *buf_, size_t len, s->rlayer.wpend_tot = 0; s->rlayer.wpend_type = type; s->rlayer.wpend_buf = buf; - s->rlayer.wpend_ret = len; } if (tot == len) { /* done? */ @@ -1368,7 +1366,7 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, prev = s->rlayer.rrlnext; if (SSL_CONNECTION_IS_DTLS(s) && level != OSSL_RECORD_PROTECTION_LEVEL_NONE) - epoch = DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer) + 1; /* new epoch */ + epoch = dtls1_get_epoch(s, SSL3_CC_READ); /* new epoch */ #ifndef OPENSSL_NO_DGRAM if (SSL_CONNECTION_IS_DTLS(s)) @@ -1385,7 +1383,7 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, } else { if (SSL_CONNECTION_IS_DTLS(s) && level != OSSL_RECORD_PROTECTION_LEVEL_NONE) - epoch = DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer) + 1; /* new epoch */ + epoch = dtls1_get_epoch(s, SSL3_CC_WRITE); /* new epoch */ } /* diff --git a/libs/openssl-3/ssl/record/record.h b/libs/openssl-3/ssl/record/record.h index 0f2ac2619..9a076a1fb 100644 --- a/libs/openssl-3/ssl/record/record.h +++ b/libs/openssl-3/ssl/record/record.h @@ -43,11 +43,6 @@ typedef struct tls_record_st { #endif } TLS_RECORD; -typedef struct record_pqueue_st { - uint16_t epoch; - struct pqueue_st *q; -} record_pqueue; - typedef struct dtls_record_layer_st { /* * The current data and handshake epoch. This is initially @@ -62,7 +57,7 @@ typedef struct dtls_record_layer_st { * Finished to prevent either protocol violation or unnecessary message * loss. */ - record_pqueue buffered_app_data; + struct pqueue_st *buffered_app_data; } DTLS_RECORD_LAYER; /***************************************************************************** @@ -108,8 +103,6 @@ typedef struct record_layer_st { /* number bytes written */ size_t wpend_tot; uint8_t wpend_type; - /* number of bytes submitted */ - size_t wpend_ret; const unsigned char *wpend_buf; /* Count of the number of consecutive warning alerts received */ @@ -139,7 +132,6 @@ typedef struct record_layer_st { #define RECORD_LAYER_set_read_ahead(rl, ra) ((rl)->read_ahead = (ra)) #define RECORD_LAYER_get_read_ahead(rl) ((rl)->read_ahead) -#define DTLS_RECORD_LAYER_get_w_epoch(rl) ((rl)->d->w_epoch) void RECORD_LAYER_init(RECORD_LAYER *rl, SSL_CONNECTION *s); int RECORD_LAYER_clear(RECORD_LAYER *rl); @@ -166,6 +158,7 @@ __owur int dtls1_write_bytes(SSL_CONNECTION *s, uint8_t type, const void *buf, int do_dtls1_write(SSL_CONNECTION *s, uint8_t type, const unsigned char *buf, size_t len, size_t *written); void dtls1_increment_epoch(SSL_CONNECTION *s, int rw); +uint16_t dtls1_get_epoch(SSL_CONNECTION *s, int rw); int ssl_release_record(SSL_CONNECTION *s, TLS_RECORD *rr, size_t length); # define HANDLE_RLAYER_READ_RETURN(s, ret) \ diff --git a/libs/openssl-3/ssl/record/record_local.h b/libs/openssl-3/ssl/record/record_local.h index 7bcbd14f2..1acb588f8 100644 --- a/libs/openssl-3/ssl/record/record_local.h +++ b/libs/openssl-3/ssl/record/record_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,7 +15,3 @@ *****************************************************************************/ #define MAX_WARN_ALERT_COUNT 5 - -/* Functions/macros provided by the RECORD_LAYER component */ - -#define DTLS_RECORD_LAYER_get_r_epoch(rl) ((rl)->d->r_epoch) diff --git a/libs/openssl-3/ssl/rio/poll_immediate.c b/libs/openssl-3/ssl/rio/poll_immediate.c new file mode 100644 index 000000000..66e613a7d --- /dev/null +++ b/libs/openssl-3/ssl/rio/poll_immediate.c @@ -0,0 +1,126 @@ +/* + * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/common.h" +#include +#include +#include "../ssl_local.h" + +#define ITEM_N(items, stride, n) \ + (*(SSL_POLL_ITEM *)((char *)(items) + (n)*(stride))) + +#define FAIL_FROM(n) \ + do { \ + size_t j; \ + \ + for (j = (n); j < num_items; ++j) \ + ITEM_N(items, stride, j).revents = 0; \ + \ + ok = 0; \ + goto out; \ + } while (0) + +#define FAIL_ITEM(i) \ + do { \ + ITEM_N(items, stride, i).revents = SSL_POLL_EVENT_F; \ + ++result_count; \ + FAIL_FROM(i + 1); \ + } while (0) + +int SSL_poll(SSL_POLL_ITEM *items, + size_t num_items, + size_t stride, + const struct timeval *timeout, + uint64_t flags, + size_t *p_result_count) +{ + int ok = 1; + size_t i, result_count = 0; + SSL_POLL_ITEM *item; + SSL *ssl; + uint64_t revents; + ossl_unused uint64_t events; + ossl_unused int do_tick = ((flags & SSL_POLL_FLAG_NO_HANDLE_EVENTS) == 0); + int is_immediate + = (timeout != NULL + && timeout->tv_sec == 0 && timeout->tv_usec == 0); + + /* + * Prevent calls which use SSL_poll functionality which is not currently + * supported. + */ + if (!is_immediate) { + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll does not currently support blocking " + "operation"); + FAIL_FROM(0); + } + + /* Trivial case. */ + if (num_items == 0) + goto out; + + /* Poll current state of each item. */ + for (i = 0; i < num_items; ++i) { + item = &ITEM_N(items, stride, i); + events = item->events; + revents = 0; + + switch (item->desc.type) { + case BIO_POLL_DESCRIPTOR_TYPE_SSL: + ssl = item->desc.value.ssl; + if (ssl == NULL) + /* NULL items are no-ops and have revents reported as 0 */ + break; + + switch (ssl->type) { +#ifndef OPENSSL_NO_QUIC + case SSL_TYPE_QUIC_CONNECTION: + case SSL_TYPE_QUIC_XSO: + if (!ossl_quic_conn_poll_events(ssl, events, do_tick, &revents)) + /* above call raises ERR */ + FAIL_ITEM(i); + + if (revents != 0) + ++result_count; + + break; +#endif + + default: + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll currently only supports QUIC SSL " + "objects"); + FAIL_ITEM(i); + } + break; + case BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD: + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll currently does not support polling " + "sockets"); + FAIL_ITEM(i); + default: + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll does not support unknown poll descriptor " + "type %d", item->desc.type); + FAIL_ITEM(i); + } + + item->revents = revents; + } + + /* TODO(QUIC POLLING): Blocking mode */ + /* TODO(QUIC POLLING): Support for polling FDs */ + +out: + if (p_result_count != NULL) + *p_result_count = result_count; + + return ok; +} diff --git a/libs/openssl-3/ssl/s3_enc.c b/libs/openssl-3/ssl/s3_enc.c index 54c47dd3f..878556b06 100644 --- a/libs/openssl-3/ssl/s3_enc.c +++ b/libs/openssl-3/ssl/s3_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. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -120,6 +120,7 @@ int ssl3_change_cipher_state(SSL_CONNECTION *s, int which) md_len = (size_t)mdi; key_len = EVP_CIPHER_get_key_length(ciph); iv_len = EVP_CIPHER_get_iv_length(ciph); + if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { mac_secret = &(p[0]); @@ -374,7 +375,7 @@ int ssl3_generate_master_secret(SSL_CONNECTION *s, unsigned char *out, unsigned char *p, size_t len, size_t *secret_size) { - static const unsigned char *salt[3] = { + static const unsigned char *const salt[3] = { #ifndef CHARSET_EBCDIC (const unsigned char *)"A", (const unsigned char *)"BB", diff --git a/libs/openssl-3/ssl/s3_lib.c b/libs/openssl-3/ssl/s3_lib.c index 7fe8de4e8..2bc5e79fd 100644 --- a/libs/openssl-3/ssl/s3_lib.c +++ b/libs/openssl-3/ssl/s3_lib.c @@ -4287,15 +4287,15 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl } for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + int minversion, maxversion; + c = sk_SSL_CIPHER_value(prio, i); + minversion = SSL_CONNECTION_IS_DTLS(s) ? c->min_dtls : c->min_tls; + maxversion = SSL_CONNECTION_IS_DTLS(s) ? c->max_dtls : c->max_tls; /* Skip ciphers not supported by the protocol version */ - if (!SSL_CONNECTION_IS_DTLS(s) && - ((s->version < c->min_tls) || (s->version > c->max_tls))) - continue; - if (SSL_CONNECTION_IS_DTLS(s) && - (DTLS_VERSION_LT(s->version, c->min_dtls) || - DTLS_VERSION_GT(s->version, c->max_dtls))) + if (ssl_version_cmp(s, s->version, minversion) < 0 + || ssl_version_cmp(s, s->version, maxversion) > 0) continue; /* diff --git a/libs/openssl-3/ssl/ssl_cert.c b/libs/openssl-3/ssl/ssl_cert.c index 126be668f..f11eb7582 100644 --- a/libs/openssl-3/ssl/ssl_cert.c +++ b/libs/openssl-3/ssl/ssl_cert.c @@ -1240,13 +1240,13 @@ int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx) return 0; } -SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_CTX *ctx) +const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_CTX *ctx) { size_t i; /* check classic pk types */ for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { - SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i]; + const SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i]; if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid)) || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) { @@ -1270,7 +1270,7 @@ SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_C return NULL; } -SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx) +const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx) { if (idx >= (OSSL_NELEM(ssl_cert_info) + ctx->sigalg_list_len)) return NULL; diff --git a/libs/openssl-3/ssl/ssl_cert_table.h b/libs/openssl-3/ssl/ssl_cert_table.h index 28918b976..e4dc8063b 100644 --- a/libs/openssl-3/ssl/ssl_cert_table.h +++ b/libs/openssl-3/ssl/ssl_cert_table.h @@ -10,7 +10,7 @@ /* * Certificate table information. NB: table entries must match SSL_PKEY indices */ -static SSL_CERT_LOOKUP ssl_cert_info [] = { +static const SSL_CERT_LOOKUP ssl_cert_info [] = { {EVP_PKEY_RSA, SSL_aRSA}, /* SSL_PKEY_RSA */ {EVP_PKEY_RSA_PSS, SSL_aRSA}, /* SSL_PKEY_RSA_PSS_SIGN */ {EVP_PKEY_DSA, SSL_aDSS}, /* SSL_PKEY_DSA_SIGN */ diff --git a/libs/openssl-3/ssl/ssl_ciph.c b/libs/openssl-3/ssl/ssl_ciph.c index 8360991ce..ddde21b96 100644 --- a/libs/openssl-3/ssl/ssl_ciph.c +++ b/libs/openssl-3/ssl/ssl_ciph.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. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -1708,7 +1708,7 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) const char *ver; const char *kx, *au, *enc, *mac; uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; - static const char *format = "%-30s %-7s Kx=%-8s Au=%-5s Enc=%-22s Mac=%-4s\n"; + static const char *const format = "%-30s %-7s Kx=%-8s Au=%-5s Enc=%-22s Mac=%-4s\n"; if (buf == NULL) { len = 128; @@ -2221,6 +2221,8 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, in = 1; /* padding length byte */ out = EVP_CIPHER_get_iv_length(e_ciph); blk = EVP_CIPHER_get_block_size(e_ciph); + if (blk == 0) + return 0; } } @@ -2234,7 +2236,7 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, int ssl_cert_is_disabled(SSL_CTX *ctx, size_t idx) { - SSL_CERT_LOOKUP *cl; + const SSL_CERT_LOOKUP *cl; /* A provider-loaded key type is always enabled */ if (idx >= SSL_PKEY_NUM) diff --git a/libs/openssl-3/ssl/ssl_conf.c b/libs/openssl-3/ssl/ssl_conf.c index 8b07a1466..77de00542 100644 --- a/libs/openssl-3/ssl/ssl_conf.c +++ b/libs/openssl-3/ssl/ssl_conf.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-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 @@ -241,7 +241,7 @@ static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value) return 1; /* ECDHParameters accepts a single group name */ - if (strstr(value, ":") != NULL) + if (strchr(value, ':') != NULL) return 0; if (cctx->ctx) @@ -391,6 +391,7 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC), SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION), SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX), + SSL_FLAG_TBL("PreferNoDHEKEX", SSL_OP_PREFER_NO_DHE_KEX), SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA), SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT), SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY), @@ -725,6 +726,7 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_CLIENT), SSL_CONF_CMD_SWITCH("allow_no_dhe_kex", 0), + SSL_CONF_CMD_SWITCH("prefer_no_dhe_kex", 0), SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("strict", 0), SSL_CONF_CMD_SWITCH("no_middlebox", 0), @@ -816,6 +818,8 @@ static const ssl_switch_tbl ssl_cmd_switches[] = { {SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV}, /* allow_no_dhe_kex */ {SSL_OP_ALLOW_NO_DHE_KEX, 0}, + /* prefer_no_dhe_kex */ + {SSL_OP_PREFER_NO_DHE_KEX, 0}, /* chacha reprioritization */ {SSL_OP_PRIORITIZE_CHACHA, 0}, {SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */ diff --git a/libs/openssl-3/ssl/ssl_err.c b/libs/openssl-3/ssl/ssl_err.c index 0631ff571..f5fb4107f 100644 --- a/libs/openssl-3/ssl/ssl_err.c +++ b/libs/openssl-3/ssl/ssl_err.c @@ -180,6 +180,10 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "failed to get parameter"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_INIT_ASYNC), "failed to init async"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FEATURE_NEGOTIATION_NOT_COMPLETE), + "feature negotiation not complete"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FEATURE_NOT_RENEGOTIABLE), + "feature not renegotiable"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FRAGMENTED_CLIENT_HELLO), "fragmented client hello"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_GOT_A_FIN_BEFORE_A_CCS), @@ -347,6 +351,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "pem name bad prefix"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PEM_NAME_TOO_SHORT), "pem name too short"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PIPELINE_FAILURE), "pipeline failure"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_POLL_REQUEST_NOT_SUPPORTED), + "poll request not supported"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR), "post handshake auth encoding err"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PRIVATE_KEY_MISMATCH), @@ -568,6 +574,12 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "unsolicited extension"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), "unsupported compression algorithm"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_CONFIG_VALUE), + "unsupported config value"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS), + "unsupported config value class"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_CONFIG_VALUE_OP), + "unsupported config value op"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), "unsupported elliptic curve"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_PROTOCOL), @@ -576,6 +588,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "unsupported ssl version"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_WRITE_FLAG), + "unsupported write flag"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_VERSION_TOO_HIGH), "version too high"}, diff --git a/libs/openssl-3/ssl/ssl_lib.c b/libs/openssl-3/ssl/ssl_lib.c index 016135fe1..5ec6ac4b6 100644 --- a/libs/openssl-3/ssl/ssl_lib.c +++ b/libs/openssl-3/ssl/ssl_lib.c @@ -62,7 +62,7 @@ static int ssl_undefined_function_8(SSL_CONNECTION *sc) return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc)); } -SSL3_ENC_METHOD ssl3_undef_enc_method = { +const SSL3_ENC_METHOD ssl3_undef_enc_method = { ssl_undefined_function_8, ssl_undefined_function_3, ssl_undefined_function_4, @@ -343,7 +343,7 @@ static int dane_tlsa_add(SSL_DANE *dane, /* * The Full(0) certificate decodes to a seemingly valid X.509 * object with a plausible key, so the TLSA record is well - * formed. However, we don't actually need the certifiate for + * formed. However, we don't actually need the certificate for * usages PKIX-EE(1) or DANE-EE(3), because at least the EE * certificate is always presented by the peer. We discard the * certificate, and just use the TLSA data as an opaque blob @@ -1917,7 +1917,7 @@ int SSL_has_pending(const SSL *s) TLS_RECORD *rdata; pitem *item, *iter; - iter = pqueue_iterator(sc->rlayer.d->buffered_app_data.q); + iter = pqueue_iterator(sc->rlayer.d->buffered_app_data); while ((item = pqueue_next(&iter)) != NULL) { rdata = item->data; if (rdata->length > 0) @@ -2483,13 +2483,14 @@ int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *readbytes) return ret; } -int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) +int ssl_write_internal(SSL *s, const void *buf, size_t num, + uint64_t flags, size_t *written) { SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); #ifndef OPENSSL_NO_QUIC if (IS_QUIC(s)) - return s->method->ssl_write(s, buf, num, written); + return ossl_quic_write_flags(s, buf, num, flags, written); #endif if (sc == NULL) @@ -2506,6 +2507,11 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) return -1; } + if (flags != 0) { + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_WRITE_FLAG); + return -1; + } + if (sc->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY || sc->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY || sc->early_data_state == SSL_EARLY_DATA_READ_RETRY) { @@ -2611,7 +2617,7 @@ int SSL_write(SSL *s, const void *buf, int num) return -1; } - ret = ssl_write_internal(s, buf, (size_t)num, &written); + ret = ssl_write_internal(s, buf, (size_t)num, 0, &written); /* * The cast is safe here because ret should be <= INT_MAX because num is @@ -2625,7 +2631,13 @@ int SSL_write(SSL *s, const void *buf, int num) int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written) { - int ret = ssl_write_internal(s, buf, num, written); + return SSL_write_ex2(s, buf, num, 0, written); +} + +int SSL_write_ex2(SSL *s, const void *buf, size_t num, uint64_t flags, + size_t *written) +{ + int ret = ssl_write_internal(s, buf, num, flags, written); if (ret < 0) ret = 0; @@ -4203,6 +4215,9 @@ void SSL_CTX_free(SSL_CTX *a) #endif OPENSSL_free(a->propq); +#ifndef OPENSSL_NO_QLOG + OPENSSL_free(a->qlog_title); +#endif OPENSSL_free(a); } @@ -4777,12 +4792,6 @@ int ssl_undefined_const_function(const SSL *s) return 0; } -const SSL_METHOD *ssl_bad_method(int ver) -{ - ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return NULL; -} - const char *ssl_protocol_to_string(int version) { switch (version) @@ -7629,6 +7638,30 @@ int SSL_get_conn_close_info(SSL *s, SSL_CONN_CLOSE_INFO *info, #endif } +int SSL_get_value_uint(SSL *s, uint32_t class_, uint32_t id, + uint64_t *value) +{ +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_get_value_uint(s, class_, id, value); +#endif + + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL); + return 0; +} + +int SSL_set_value_uint(SSL *s, uint32_t class_, uint32_t id, + uint64_t value) +{ +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_set_value_uint(s, class_, id, value); +#endif + + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL); + return 0; +} + int SSL_add_expected_rpk(SSL *s, EVP_PKEY *rpk) { unsigned char *data = NULL; diff --git a/libs/openssl-3/ssl/ssl_local.h b/libs/openssl-3/ssl/ssl_local.h index 535568f10..f448cfdbc 100644 --- a/libs/openssl-3/ssl/ssl_local.h +++ b/libs/openssl-3/ssl/ssl_local.h @@ -1189,6 +1189,10 @@ struct ssl_ctx_st { size_t client_cert_type_len; unsigned char *server_cert_type; size_t server_cert_type_len; + +# ifndef OPENSSL_NO_QLOG + char *qlog_title; /* Session title for qlog */ +# endif }; typedef struct cert_pkey_st CERT_PKEY; @@ -2233,9 +2237,8 @@ typedef enum downgrade_en { extern const unsigned char tls11downgrade[8]; extern const unsigned char tls12downgrade[8]; -extern SSL3_ENC_METHOD ssl3_undef_enc_method; +extern const SSL3_ENC_METHOD ssl3_undef_enc_method; -__owur const SSL_METHOD *ssl_bad_method(int ver); __owur const SSL_METHOD *sslv3_method(void); __owur const SSL_METHOD *sslv3_server_method(void); __owur const SSL_METHOD *sslv3_client_method(void); @@ -2464,7 +2467,8 @@ void ossl_ssl_connection_free(SSL *ssl); __owur int ossl_ssl_connection_reset(SSL *ssl); __owur int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes); -__owur int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written); +__owur int ssl_write_internal(SSL *s, const void *buf, size_t num, + uint64_t flags, size_t *written); int ssl_clear_bad_session(SSL_CONNECTION *s); __owur CERT *ssl_cert_new(size_t ssl_pkey_num); __owur CERT *ssl_cert_dup(CERT *cert); @@ -2531,10 +2535,10 @@ __owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp); __owur int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx); -__owur SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, - size_t *pidx, - SSL_CTX *ctx); -__owur SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx); +__owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, + size_t *pidx, + SSL_CTX *ctx); +__owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx); int ssl_undefined_function(SSL *s); __owur int ssl_undefined_void_function(void); @@ -2629,6 +2633,7 @@ __owur int ssl3_handshake_write(SSL_CONNECTION *s); __owur int ssl_allow_compression(SSL_CONNECTION *s); +__owur int ssl_version_cmp(const SSL_CONNECTION *s, int versiona, int versionb); __owur int ssl_version_supported(const SSL_CONNECTION *s, int version, const SSL_METHOD **meth); diff --git a/libs/openssl-3/ssl/ssl_sess.c b/libs/openssl-3/ssl/ssl_sess.c index 254de4a09..3857e027e 100644 --- a/libs/openssl-3/ssl/ssl_sess.c +++ b/libs/openssl-3/ssl/ssl_sess.c @@ -941,15 +941,20 @@ long SSL_SESSION_get_timeout(const SSL_SESSION *s) } long SSL_SESSION_get_time(const SSL_SESSION *s) +{ + return (long) SSL_SESSION_get_time_ex(s); +} + +time_t SSL_SESSION_get_time_ex(const SSL_SESSION *s) { if (s == NULL) return 0; - return (long)ossl_time_to_time_t(s->time); + return ossl_time_to_time_t(s->time); } -long SSL_SESSION_set_time(SSL_SESSION *s, long t) +time_t SSL_SESSION_set_time_ex(SSL_SESSION *s, time_t t) { - OSSL_TIME new_time = ossl_time_from_time_t((time_t)t); + OSSL_TIME new_time = ossl_time_from_time_t(t); if (s == NULL) return 0; @@ -967,6 +972,11 @@ long SSL_SESSION_set_time(SSL_SESSION *s, long t) return t; } +long SSL_SESSION_set_time(SSL_SESSION *s, long t) +{ + return (long) SSL_SESSION_set_time_ex(s, (time_t) t); +} + int SSL_SESSION_get_protocol_version(const SSL_SESSION *s) { return s->ssl_version; diff --git a/libs/openssl-3/ssl/sslerr.h b/libs/openssl-3/ssl/sslerr.h index f28230f08..7d2bbd6c4 100644 --- a/libs/openssl-3/ssl/sslerr.h +++ b/libs/openssl-3/ssl/sslerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 diff --git a/libs/openssl-3/ssl/statem/extensions_srvr.c b/libs/openssl-3/ssl/statem/extensions_srvr.c index 64ccb3ed6..21db977c8 100644 --- a/libs/openssl-3/ssl/statem/extensions_srvr.c +++ b/libs/openssl-3/ssl/statem/extensions_srvr.c @@ -573,6 +573,21 @@ int tls_parse_ctos_psk_kex_modes(SSL_CONNECTION *s, PACKET *pkt, && (s->options & SSL_OP_ALLOW_NO_DHE_KEX) != 0) s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE; } + + if (((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) != 0) + && (s->options & SSL_OP_PREFER_NO_DHE_KEX) != 0) { + + /* + * If NO_DHE is supported and preferred, then we only remember this + * mode. DHE PSK will not be used for sure, because in any case where + * it would be supported (i.e. if a key share is present), NO_DHE would + * be supported as well. As the latter is preferred it would be + * chosen. By removing DHE PSK here, we don't have to deal with the + * SSL_OP_PREFER_NO_DHE_KEX option in any other place. + */ + s->ext.psk_kex_mode = TLSEXT_KEX_MODE_FLAG_KE; + } + #endif return 1; @@ -1645,10 +1660,13 @@ EXT_RETURN tls_construct_stoc_key_share(SSL_CONNECTION *s, WPACKET *pkt, } return EXT_RETURN_NOT_SENT; } + if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) { /* - * PSK ('hit') and explicitly not doing DHE (if the client sent the - * DHE option we always take it); don't send key share. + * PSK ('hit') and explicitly not doing DHE. If the client sent the + * DHE option, we take it by default, except if non-DHE would be + * preferred by config, but this case would have been handled in + * tls_parse_ctos_psk_kex_modes(). */ return EXT_RETURN_NOT_SENT; } diff --git a/libs/openssl-3/ssl/statem/statem_clnt.c b/libs/openssl-3/ssl/statem/statem_clnt.c index cbf5a57be..7d8b14037 100644 --- a/libs/openssl-3/ssl/statem/statem_clnt.c +++ b/libs/openssl-3/ssl/statem/statem_clnt.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. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -871,20 +871,16 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst) return WORK_ERROR; } - if (SSL_CONNECTION_IS_DTLS(s)) { #ifndef OPENSSL_NO_SCTP - if (s->hit) { - /* - * Change to new shared key of SCTP-Auth, will be ignored if - * no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, - 0, NULL); - } -#endif - - dtls1_increment_epoch(s, SSL3_CC_WRITE); + if (SSL_CONNECTION_IS_DTLS(s) && s->hit) { + /* + * Change to new shared key of SCTP-Auth, will be ignored if + * no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + 0, NULL); } +#endif break; case TLS_ST_CW_FINISHED: @@ -1427,6 +1423,10 @@ static int set_client_ciphersuite(SSL_CONNECTION *s, if (SSL_CONNECTION_IS_TLS13(s)) { const EVP_MD *md = ssl_md(sctx, c->algorithm2); + if (!ossl_assert(s->session->cipher != NULL)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } /* * In TLSv1.3 it is valid for the server to select a different * ciphersuite as long as the hash is the same. @@ -4115,15 +4115,12 @@ int ssl_cipher_list_to_bytes(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *sk, /* Sanity check that the maximum version we offer has ciphers enabled */ if (!maxverok) { - if (SSL_CONNECTION_IS_DTLS(s)) { - if (DTLS_VERSION_GE(c->max_dtls, s->s3.tmp.max_ver) - && DTLS_VERSION_LE(c->min_dtls, s->s3.tmp.max_ver)) - maxverok = 1; - } else { - if (c->max_tls >= s->s3.tmp.max_ver - && c->min_tls <= s->s3.tmp.max_ver) - maxverok = 1; - } + int minproto = SSL_CONNECTION_IS_DTLS(s) ? c->min_dtls : c->min_tls; + int maxproto = SSL_CONNECTION_IS_DTLS(s) ? c->max_dtls : c->max_tls; + + if (ssl_version_cmp(s, maxproto, s->s3.tmp.max_ver) >= 0 + && ssl_version_cmp(s, minproto, s->s3.tmp.max_ver) <= 0) + maxverok = 1; } totlen += len; @@ -4142,7 +4139,7 @@ int ssl_cipher_list_to_bytes(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *sk, if (totlen != 0) { if (empty_reneg_info_scsv) { - static SSL_CIPHER scsv = { + static const SSL_CIPHER scsv = { 0, NULL, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (!ssl->method->put_cipher_by_char(&scsv, pkt, &len)) { @@ -4151,7 +4148,7 @@ int ssl_cipher_list_to_bytes(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *sk, } } if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { - static SSL_CIPHER scsv = { + static const SSL_CIPHER scsv = { 0, NULL, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (!ssl->method->put_cipher_by_char(&scsv, pkt, &len)) { diff --git a/libs/openssl-3/ssl/statem/statem_dtls.c b/libs/openssl-3/ssl/statem/statem_dtls.c index c674ddfb5..b37ac80a6 100644 --- a/libs/openssl-3/ssl/statem/statem_dtls.c +++ b/libs/openssl-3/ssl/statem/statem_dtls.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-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 @@ -39,9 +39,9 @@ if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ if (bitmask[ii] != 0xff) { is_complete = 0; break; } } -static unsigned char bitmask_start_values[] = +static const unsigned char bitmask_start_values[] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 }; -static unsigned char bitmask_end_values[] = +static const unsigned char bitmask_end_values[] = { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; static void dtls1_fix_message_header(SSL_CONNECTION *s, size_t frag_off, @@ -800,7 +800,6 @@ static int dtls1_process_out_of_seq_message(SSL_CONNECTION *s, static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, size_t *len) { - unsigned char wire[DTLS1_HM_HEADER_LENGTH]; size_t mlen, frag_off, frag_len; int i, ret; uint8_t recvd_type; @@ -808,9 +807,12 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, size_t readbytes; SSL *ssl = SSL_CONNECTION_GET_SSL(s); int chretran = 0; + unsigned char *p; *errtype = 0; + p = (unsigned char *)s->init_buf->data; + redo: /* see if we have the required fragment already */ ret = dtls1_retrieve_buffered_fragment(s, &frag_len); @@ -825,7 +827,7 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, } /* read handshake message header */ - i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, &recvd_type, wire, + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, &recvd_type, p, DTLS1_HM_HEADER_LENGTH, 0, &readbytes); if (i <= 0) { /* nbio, or an error */ s->rwstate = SSL_READING; @@ -833,13 +835,12 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, return 0; } if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) { - if (wire[0] != SSL3_MT_CCS) { + if (p[0] != SSL3_MT_CCS) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_CHANGE_CIPHER_SPEC); goto f_err; } - memcpy(s->init_buf->data, wire, readbytes); s->init_num = readbytes - 1; s->init_msg = s->init_buf->data + 1; s->s3.tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC; @@ -855,7 +856,7 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, } /* parse the message fragment header */ - dtls1_get_message_header(wire, &msg_hdr); + dtls1_get_message_header(p, &msg_hdr); mlen = msg_hdr.msg_len; frag_off = msg_hdr.frag_off; @@ -880,7 +881,7 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, if (!s->server || msg_hdr.seq != 0 || s->d1->handshake_read_seq != 1 - || wire[0] != SSL3_MT_CLIENT_HELLO + || p[0] != SSL3_MT_CLIENT_HELLO || s->statem.hand_state != DTLS_ST_SW_HELLO_VERIFY_REQUEST) { *errtype = dtls1_process_out_of_seq_message(s, &msg_hdr); return 0; @@ -901,16 +902,16 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && s->statem.hand_state != TLS_ST_OK - && wire[0] == SSL3_MT_HELLO_REQUEST) { + && p[0] == SSL3_MT_HELLO_REQUEST) { /* * The server may always send 'Hello Request' messages -- we are * doing a handshake anyway now, so ignore them if their format is * correct. Does not count for 'Finished' MAC. */ - if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { + if (p[1] == 0 && p[2] == 0 && p[3] == 0) { if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - wire, DTLS1_HM_HEADER_LENGTH, ssl, + p, DTLS1_HM_HEADER_LENGTH, ssl, s->msg_callback_arg); s->init_num = 0; @@ -928,8 +929,7 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, } if (frag_len > 0) { - unsigned char *p = - (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + p += DTLS1_HM_HEADER_LENGTH; i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, &p[frag_off], frag_len, 0, &readbytes); diff --git a/libs/openssl-3/ssl/statem/statem_lib.c b/libs/openssl-3/ssl/statem/statem_lib.c index db153d1f4..8932ac44c 100644 --- a/libs/openssl-3/ssl/statem/statem_lib.c +++ b/libs/openssl-3/ssl/statem/statem_lib.c @@ -156,17 +156,12 @@ int tls_setup_handshake(SSL_CONNECTION *s) /* Sanity check that we have MD5-SHA1 if we need it */ if (sctx->ssl_digest_methods[SSL_MD_MD5_SHA1_IDX] == NULL) { - int md5sha1_needed = 0; + int negotiated_minversion; + int md5sha1_needed_maxversion = SSL_CONNECTION_IS_DTLS(s) + ? DTLS1_VERSION : TLS1_1_VERSION; /* We don't have MD5-SHA1 - do we need it? */ - if (SSL_CONNECTION_IS_DTLS(s)) { - if (DTLS_VERSION_LE(ver_max, DTLS1_VERSION)) - md5sha1_needed = 1; - } else { - if (ver_max <= TLS1_1_VERSION) - md5sha1_needed = 1; - } - if (md5sha1_needed) { + if (ssl_version_cmp(s, ver_max, md5sha1_needed_maxversion) <= 0) { SSLfatal_data(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM, "The max supported SSL/TLS version needs the" @@ -177,14 +172,12 @@ int tls_setup_handshake(SSL_CONNECTION *s) } ok = 1; + /* Don't allow TLSv1.1 or below to be negotiated */ - if (SSL_CONNECTION_IS_DTLS(s)) { - if (DTLS_VERSION_LT(ver_min, DTLS1_2_VERSION)) - ok = SSL_set_min_proto_version(ssl, DTLS1_2_VERSION); - } else { - if (ver_min < TLS1_2_VERSION) - ok = SSL_set_min_proto_version(ssl, TLS1_2_VERSION); - } + negotiated_minversion = SSL_CONNECTION_IS_DTLS(s) ? + DTLS1_2_VERSION : TLS1_2_VERSION; + if (ssl_version_cmp(s, ver_min, negotiated_minversion) < 0) + ok = SSL_set_min_proto_version(ssl, negotiated_minversion); if (!ok) { /* Shouldn't happen */ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_INTERNAL_ERROR); @@ -204,16 +197,16 @@ int tls_setup_handshake(SSL_CONNECTION *s) */ for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); + int cipher_minprotover = SSL_CONNECTION_IS_DTLS(s) + ? c->min_dtls : c->min_tls; + int cipher_maxprotover = SSL_CONNECTION_IS_DTLS(s) + ? c->max_dtls : c->max_tls; - if (SSL_CONNECTION_IS_DTLS(s)) { - if (DTLS_VERSION_GE(ver_max, c->min_dtls) && - DTLS_VERSION_LE(ver_max, c->max_dtls)) - ok = 1; - } else if (ver_max >= c->min_tls && ver_max <= c->max_tls) { + if (ssl_version_cmp(s, ver_max, cipher_minprotover) >= 0 + && ssl_version_cmp(s, ver_max, cipher_maxprotover) <= 0) { ok = 1; - } - if (ok) break; + } } if (!ok) { SSLfatal_data(s, SSL_AD_HANDSHAKE_FAILURE, @@ -815,8 +808,6 @@ MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL_CONNECTION *s, } if (SSL_CONNECTION_IS_DTLS(s)) { - dtls1_increment_epoch(s, SSL3_CC_READ); - if (s->version == DTLS1_BAD_VER) s->d1->handshake_read_seq++; @@ -1788,15 +1779,23 @@ int ssl_allow_compression(SSL_CONNECTION *s) return ssl_security(s, SSL_SECOP_COMPRESSION, 0, 0, NULL); } -static int version_cmp(const SSL_CONNECTION *s, int a, int b) +/* + * SSL/TLS/DTLS version comparison + * + * Returns + * 0 if versiona is equal to versionb + * 1 if versiona is greater than versionb + * -1 if versiona is less than versionb + */ +int ssl_version_cmp(const SSL_CONNECTION *s, int versiona, int versionb) { int dtls = SSL_CONNECTION_IS_DTLS(s); - if (a == b) + if (versiona == versionb) return 0; if (!dtls) - return a < b ? -1 : 1; - return DTLS_VERSION_LT(a, b) ? -1 : 1; + return versiona < versionb ? -1 : 1; + return DTLS_VERSION_LT(versiona, versionb) ? -1 : 1; } typedef struct { @@ -1873,12 +1872,12 @@ static int ssl_method_error(const SSL_CONNECTION *s, const SSL_METHOD *method) int version = method->version; if ((s->min_proto_version != 0 && - version_cmp(s, version, s->min_proto_version) < 0) || + ssl_version_cmp(s, version, s->min_proto_version) < 0) || ssl_security(s, SSL_SECOP_VERSION, 0, version, NULL) == 0) return SSL_R_VERSION_TOO_LOW; if (s->max_proto_version != 0 && - version_cmp(s, version, s->max_proto_version) > 0) + ssl_version_cmp(s, version, s->max_proto_version) > 0) return SSL_R_VERSION_TOO_HIGH; if ((s->options & method->mask) != 0) @@ -1966,7 +1965,7 @@ int ssl_version_supported(const SSL_CONNECTION *s, int version, switch (SSL_CONNECTION_GET_SSL(s)->method->version) { default: /* Version should match method version for non-ANY method */ - return version_cmp(s, version, s->version) == 0; + return ssl_version_cmp(s, version, s->version) == 0; case TLS_ANY_VERSION: table = tls_version_table; break; @@ -1976,13 +1975,13 @@ int ssl_version_supported(const SSL_CONNECTION *s, int version, } for (vent = table; - vent->version != 0 && version_cmp(s, version, vent->version) <= 0; + vent->version != 0 && ssl_version_cmp(s, version, vent->version) <= 0; ++vent) { const SSL_METHOD *(*thismeth)(void) = s->server ? vent->smeth : vent->cmeth; if (thismeth != NULL - && version_cmp(s, version, vent->version) == 0 + && ssl_version_cmp(s, version, vent->version) == 0 && ssl_method_error(s, thismeth()) == 0 && (!s->server || version != TLS1_3_VERSION @@ -2156,7 +2155,7 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, switch (server_version) { default: if (!SSL_CONNECTION_IS_TLS13(s)) { - if (version_cmp(s, client_version, s->version) < 0) + if (ssl_version_cmp(s, client_version, s->version) < 0) return SSL_R_WRONG_SSL_VERSION; *dgrd = DOWNGRADE_NONE; /* @@ -2213,7 +2212,7 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, return SSL_R_BAD_LEGACY_VERSION; while (PACKET_get_net_2(&versionslist, &candidate_vers)) { - if (version_cmp(s, candidate_vers, best_vers) <= 0) + if (ssl_version_cmp(s, candidate_vers, best_vers) <= 0) continue; if (ssl_version_supported(s, candidate_vers, &best_method)) best_vers = candidate_vers; @@ -2248,7 +2247,7 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, * If the supported versions extension isn't present, then the highest * version we can negotiate is TLSv1.2 */ - if (version_cmp(s, client_version, TLS1_3_VERSION) >= 0) + if (ssl_version_cmp(s, client_version, TLS1_3_VERSION) >= 0) client_version = TLS1_2_VERSION; /* @@ -2259,7 +2258,7 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, const SSL_METHOD *method; if (vent->smeth == NULL || - version_cmp(s, client_version, vent->version) < 0) + ssl_version_cmp(s, client_version, vent->version) < 0) continue; method = vent->smeth(); if (ssl_method_error(s, method) == 0) { @@ -2347,13 +2346,8 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version, SSLfatal(s, SSL_AD_PROTOCOL_VERSION, ret); return 0; } - if (SSL_CONNECTION_IS_DTLS(s) ? DTLS_VERSION_LT(s->version, ver_min) - : s->version < ver_min) { - s->version = origv; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); - return 0; - } else if (SSL_CONNECTION_IS_DTLS(s) ? DTLS_VERSION_GT(s->version, ver_max) - : s->version > ver_max) { + if (ssl_version_cmp(s, s->version, ver_min) < 0 + || ssl_version_cmp(s, s->version, ver_max) > 0) { s->version = origv; SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); return 0; diff --git a/libs/openssl-3/ssl/statem/statem_srvr.c b/libs/openssl-3/ssl/statem/statem_srvr.c index b0cee7914..5ff479a2e 100644 --- a/libs/openssl-3/ssl/statem/statem_srvr.c +++ b/libs/openssl-3/ssl/statem/statem_srvr.c @@ -994,9 +994,6 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) /* SSLfatal() already called */ return WORK_ERROR; } - - if (SSL_CONNECTION_IS_DTLS(s)) - dtls1_increment_epoch(s, SSL3_CC_WRITE); break; case TLS_ST_SW_SRVR_DONE: @@ -1734,18 +1731,9 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) /* SSLv3/TLS */ s->client_version = clienthello->legacy_version; } - /* - * Do SSL/TLS version negotiation if applicable. For DTLS we just check - * versions are potentially compatible. Version negotiation comes later. - */ - if (!SSL_CONNECTION_IS_DTLS(s)) { - protverr = ssl_choose_server_version(s, clienthello, &dgrd); - } else if (ssl->method->version != DTLS_ANY_VERSION && - DTLS_VERSION_LT((int)clienthello->legacy_version, s->version)) { - protverr = SSL_R_VERSION_TOO_LOW; - } else { - protverr = 0; - } + + /* Choose the server SSL/TLS/DTLS version. */ + protverr = ssl_choose_server_version(s, clienthello, &dgrd); if (protverr) { if (SSL_IS_FIRST_HANDSHAKE(s)) { @@ -1783,14 +1771,6 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) } s->d1->cookie_verified = 1; } - if (ssl->method->version == DTLS_ANY_VERSION) { - protverr = ssl_choose_server_version(s, clienthello, &dgrd); - if (protverr != 0) { - s->version = s->client_version; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, protverr); - goto err; - } - } } s->hit = 0; diff --git a/libs/openssl-3/ssl/t1_enc.c b/libs/openssl-3/ssl/t1_enc.c index 94f68eb99..2e9e24a8c 100644 --- a/libs/openssl-3/ssl/t1_enc.c +++ b/libs/openssl-3/ssl/t1_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. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -228,6 +228,9 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) direction = OSSL_RECORD_DIRECTION_WRITE; } + if (SSL_CONNECTION_IS_DTLS(s)) + dtls1_increment_epoch(s, which); + if (!ssl_set_new_record_layer(s, s->version, direction, OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, NULL, 0, key, cl, iv, (size_t)k, mac_secret, @@ -425,6 +428,15 @@ int tls1_export_keying_material(SSL_CONNECTION *s, unsigned char *out, size_t vallen = 0, currentvalpos; int rv = 0; + /* + * RFC 5705 embeds context length as uint16; reject longer context + * before proceeding. + */ + if (contextlen > 0xffff) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + /* * construct PRF arguments we construct the PRF argument ourself rather * than passing separate values into the TLS PRF to ensure that the diff --git a/libs/openssl-3/ssl/t1_lib.c b/libs/openssl-3/ssl/t1_lib.c index ea1e256d6..e9aa0785d 100644 --- a/libs/openssl-3/ssl/t1_lib.c +++ b/libs/openssl-3/ssl/t1_lib.c @@ -140,7 +140,7 @@ int tls1_clear(SSL *s) } /* Legacy NID to group_id mapping. Only works for groups we know about */ -static struct { +static const struct { int nid; uint16_t group_id; } nid_to_group[] = { @@ -850,6 +850,7 @@ int tls_valid_group(SSL_CONNECTION *s, uint16_t group_id, const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(SSL_CONNECTION_GET_CTX(s), group_id); int ret; + int group_minversion, group_maxversion; if (okfortls13 != NULL) *okfortls13 = 0; @@ -857,27 +858,22 @@ int tls_valid_group(SSL_CONNECTION *s, uint16_t group_id, if (ginfo == NULL) return 0; - if (SSL_CONNECTION_IS_DTLS(s)) { - if (ginfo->mindtls < 0 || ginfo->maxdtls < 0) - return 0; - if (ginfo->maxdtls == 0) - ret = 1; - else - ret = DTLS_VERSION_LE(minversion, ginfo->maxdtls); - if (ginfo->mindtls > 0) - ret &= DTLS_VERSION_GE(maxversion, ginfo->mindtls); - } else { - if (ginfo->mintls < 0 || ginfo->maxtls < 0) - return 0; - if (ginfo->maxtls == 0) - ret = 1; - else - ret = (minversion <= ginfo->maxtls); - if (ginfo->mintls > 0) - ret &= (maxversion >= ginfo->mintls); + group_minversion = SSL_CONNECTION_IS_DTLS(s) ? ginfo->mindtls : ginfo->mintls; + group_maxversion = SSL_CONNECTION_IS_DTLS(s) ? ginfo->maxdtls : ginfo->maxtls; + + if (group_minversion < 0 || group_maxversion < 0) + return 0; + if (group_maxversion == 0) + ret = 1; + else + ret = (ssl_version_cmp(s, minversion, group_maxversion) <= 0); + if (group_minversion > 0) + ret &= (ssl_version_cmp(s, maxversion, group_minversion) >= 0); + + if (!SSL_CONNECTION_IS_DTLS(s)) { if (ret && okfortls13 != NULL && maxversion == TLS1_3_VERSION) - *okfortls13 = (ginfo->maxtls == 0) - || (ginfo->maxtls >= TLS1_3_VERSION); + *okfortls13 = (group_maxversion == 0) + || (group_maxversion >= TLS1_3_VERSION); } ret &= !isec || strcmp(ginfo->algorithm, "EC") == 0 @@ -963,6 +959,7 @@ uint16_t tls1_shared_group(SSL_CONNECTION *s, int nmatch) for (k = 0, i = 0; i < num_pref; i++) { uint16_t id = pref[i]; const TLS_GROUP_INFO *inf; + int minversion, maxversion; if (!tls1_in_list(id, supp, num_supp) || !tls_group_allowed(s, id, SSL_SECOP_CURVE_SHARED)) @@ -970,20 +967,17 @@ uint16_t tls1_shared_group(SSL_CONNECTION *s, int nmatch) inf = tls1_group_id_lookup(ctx, id); if (!ossl_assert(inf != NULL)) return 0; - if (SSL_CONNECTION_IS_DTLS(s)) { - if (inf->maxdtls == -1) - continue; - if ((inf->mindtls != 0 && DTLS_VERSION_LT(s->version, inf->mindtls)) - || (inf->maxdtls != 0 - && DTLS_VERSION_GT(s->version, inf->maxdtls))) - continue; - } else { - if (inf->maxtls == -1) - continue; - if ((inf->mintls != 0 && s->version < inf->mintls) - || (inf->maxtls != 0 && s->version > inf->maxtls)) - continue; - } + + minversion = SSL_CONNECTION_IS_DTLS(s) + ? inf->mindtls : inf->mintls; + maxversion = SSL_CONNECTION_IS_DTLS(s) + ? inf->maxdtls : inf->maxtls; + if (maxversion == -1) + continue; + if ((minversion != 0 && ssl_version_cmp(s, s->version, minversion) < 0) + || (maxversion != 0 + && ssl_version_cmp(s, s->version, maxversion) > 0)) + continue; if (nmatch == k) return id; @@ -1051,9 +1045,15 @@ static int gid_cb(const char *elem, int len, void *arg) size_t i; uint16_t gid = 0; char etmp[GROUP_NAME_BUFFER_LENGTH]; + int ignore_unknown = 0; if (elem == NULL) return 0; + if (elem[0] == '?') { + ignore_unknown = 1; + ++elem; + --len; + } if (garg->gidcnt == garg->gidmax) { uint16_t *tmp = OPENSSL_realloc(garg->gid_arr, @@ -1070,13 +1070,14 @@ static int gid_cb(const char *elem, int len, void *arg) gid = tls1_group_name2id(garg->ctx, etmp); if (gid == 0) { - ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT, - "group '%s' cannot be set", etmp); - return 0; + /* Unknown group - ignore, if ignore_unknown */ + return ignore_unknown; } for (i = 0; i < garg->gidcnt; i++) - if (garg->gid_arr[i] == gid) - return 0; + if (garg->gid_arr[i] == gid) { + /* Duplicate group - ignore */ + return 1; + } garg->gid_arr[garg->gidcnt++] = gid; return 1; } @@ -1097,6 +1098,11 @@ int tls1_set_groups_list(SSL_CTX *ctx, uint16_t **pext, size_t *pextlen, gcb.ctx = ctx; if (!CONF_parse_list(str, ':', 1, gid_cb, &gcb)) goto end; + if (gcb.gidcnt == 0) { + ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT, + "No valid groups in '%s'", str); + goto end; + } if (pext == NULL) { ret = 1; goto end; @@ -2062,6 +2068,9 @@ int ssl_set_client_disabled(SSL_CONNECTION *s) int ssl_cipher_disabled(const SSL_CONNECTION *s, const SSL_CIPHER *c, int op, int ecdhe) { + int minversion = SSL_CONNECTION_IS_DTLS(s) ? c->min_dtls : c->min_tls; + int maxversion = SSL_CONNECTION_IS_DTLS(s) ? c->max_dtls : c->max_tls; + if (c->algorithm_mkey & s->s3.tmp.mask_k || c->algorithm_auth & s->s3.tmp.mask_a) return 1; @@ -2079,23 +2088,17 @@ int ssl_cipher_disabled(const SSL_CONNECTION *s, const SSL_CIPHER *c, return 1; } - if (!SSL_CONNECTION_IS_DTLS(s)) { - int min_tls = c->min_tls; - - /* - * For historical reasons we will allow ECHDE to be selected by a server - * in SSLv3 if we are a client - */ - if (min_tls == TLS1_VERSION && ecdhe - && (c->algorithm_mkey & (SSL_kECDHE | SSL_kECDHEPSK)) != 0) - min_tls = SSL3_VERSION; + /* + * For historical reasons we will allow ECHDE to be selected by a server + * in SSLv3 if we are a client + */ + if (minversion == TLS1_VERSION + && ecdhe + && (c->algorithm_mkey & (SSL_kECDHE | SSL_kECDHEPSK)) != 0) + minversion = SSL3_VERSION; - if ((min_tls > s->s3.tmp.max_ver) || (c->max_tls < s->s3.tmp.min_ver)) - return 1; - } - if (SSL_CONNECTION_IS_DTLS(s) - && (DTLS_VERSION_GT(c->min_dtls, s->s3.tmp.max_ver) - || DTLS_VERSION_LT(c->max_dtls, s->s3.tmp.min_ver))) + if (ssl_version_cmp(s, minversion, s->s3.tmp.max_ver) > 0 + || ssl_version_cmp(s, maxversion, s->s3.tmp.min_ver) < 0) return 1; return !ssl_security(s, op, c->strength_bits, 0, (void *)c); @@ -2881,8 +2884,15 @@ static int sig_cb(const char *elem, int len, void *arg) const SIGALG_LOOKUP *s; char etmp[TLS_MAX_SIGSTRING_LEN], *p; int sig_alg = NID_undef, hash_alg = NID_undef; + int ignore_unknown = 0; + if (elem == NULL) return 0; + if (elem[0] == '?') { + ignore_unknown = 1; + ++elem; + --len; + } if (sarg->sigalgcnt == TLS_MAX_SIGALGCNT) return 0; if (len > (int)(sizeof(etmp) - 1)) @@ -2922,8 +2932,10 @@ static int sig_cb(const char *elem, int len, void *arg) break; } } - if (i == OSSL_NELEM(sigalg_lookup_tbl)) - return 0; + if (i == OSSL_NELEM(sigalg_lookup_tbl)) { + /* Ignore unknown algorithms if ignore_unknown */ + return ignore_unknown; + } } } else { *p = 0; @@ -2932,8 +2944,10 @@ static int sig_cb(const char *elem, int len, void *arg) return 0; get_sigorhash(&sig_alg, &hash_alg, etmp); get_sigorhash(&sig_alg, &hash_alg, p); - if (sig_alg == NID_undef || hash_alg == NID_undef) - return 0; + if (sig_alg == NID_undef || hash_alg == NID_undef) { + /* Ignore unknown algorithms if ignore_unknown */ + return ignore_unknown; + } for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); i++, s++) { if (s->hash == hash_alg && s->sig == sig_alg) { @@ -2941,15 +2955,17 @@ static int sig_cb(const char *elem, int len, void *arg) break; } } - if (i == OSSL_NELEM(sigalg_lookup_tbl)) - return 0; + if (i == OSSL_NELEM(sigalg_lookup_tbl)) { + /* Ignore unknown algorithms if ignore_unknown */ + return ignore_unknown; + } } - /* Reject duplicates */ + /* Ignore duplicates */ for (i = 0; i < sarg->sigalgcnt - 1; i++) { if (sarg->sigalgs[i] == sarg->sigalgs[sarg->sigalgcnt - 1]) { sarg->sigalgcnt--; - return 0; + return 1; } } return 1; @@ -2969,6 +2985,11 @@ int tls1_set_sigalgs_list(SSL_CTX *ctx, CERT *c, const char *str, int client) } if (!CONF_parse_list(str, ':', 1, sig_cb, &sig)) return 0; + if (sig.sigalgcnt == 0) { + ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT, + "No valid signature algorithms in '%s'", str); + return 0; + } if (c == NULL) return 1; return tls1_set_raw_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client); diff --git a/libs/openssl-3/ssl/t1_trce.c b/libs/openssl-3/ssl/t1_trce.c index b05012f74..29dce65e4 100644 --- a/libs/openssl-3/ssl/t1_trce.c +++ b/libs/openssl-3/ssl/t1_trce.c @@ -545,6 +545,8 @@ static const ssl_trace_tbl ssl_groups_tbl[] = { {258, "ffdhe4096"}, {259, "ffdhe6144"}, {260, "ffdhe8192"}, + {25497, "X25519Kyber768Draft00"}, + {25498, "SecP256r1Kyber768Draft00"}, {0xFF01, "arbitrary_explicit_prime_curves"}, {0xFF02, "arbitrary_explicit_char2_curves"} }; diff --git a/src/NetBox/NetBox.rc b/src/NetBox/NetBox.rc index 65f8d8a18..cb10e43ce 100644 --- a/src/NetBox/NetBox.rc +++ b/src/NetBox/NetBox.rc @@ -12,13 +12,13 @@ FILETYPE 0x2 { VALUE "CompanyName", "Mikhail Lukashov\0" VALUE "FileDescription", "NetBox: SFTP/FTP/FTPS/SCP/WebDAV/S3 client for Far Manager 3.0\0" - VALUE "FileVersion", "24.5.0.602\0" + VALUE "FileVersion", "24.6.1.604\0" VALUE "InternalName", "FarNetBox\0" VALUE "LegalCopyright", "(c) 2011, 2024 Mikhail Lukashov\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "NetBox.dll\0" VALUE "ProductName", "NetBox\0" - VALUE "ProductVersion", "24.5.0.602\0" + VALUE "ProductVersion", "24.6.1.604\0" VALUE "ReleaseType", "beta\0" VALUE "WWW", "https://github.com/michaellukashov/Far-NetBox\0" } diff --git a/src/NetBox/NetBoxEng.lng b/src/NetBox/NetBoxEng.lng index acab237e1..21d8bd49e 100644 --- a/src/NetBox/NetBoxEng.lng +++ b/src/NetBox/NetBoxEng.lng @@ -746,7 +746,7 @@ "Password (user/private key):" "Prompt for password upon connection" "Show password" -"Public and private key file:" +"Private key file (.ppk):" "URL can not be empty" "Invalid URL" "The session name can not be empty" @@ -981,7 +981,7 @@ "An operation was attempted on a file for which a delete operation is pending." "The file is corrupt; an filesystem integrity check should be run." "File '%s' does not contain private key in known format." -"**Private key file '%s' contains key in %s format. WinSCP supports only PuTTY format.**" +"**Private key file '%s' contains key in %s format. WinSCP supports only PuTTY (.ppk) format.**" "Private key file '%s' contains key in deprecated SSH-1 format." "Cannot overwrite remote file '%s'.$$\n \nPress 'Delete' to delete the file and create new one instead of overwriting it.$$" "&Delete" @@ -1265,7 +1265,7 @@ "http://filezilla-project.org/" "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit %s." "Copyright © 1998-2024 The OpenSSL Project" -"3.2.1" +"3.3.1" "http://www.openssl.org/" "WebDAV code based on neon library %s" "Copyright В© 1999-2016 Joe Orton" diff --git a/src/NetBox/NetBoxPol.lng b/src/NetBox/NetBoxPol.lng index 8f287962b..8bf78e45a 100644 --- a/src/NetBox/NetBoxPol.lng +++ b/src/NetBox/NetBoxPol.lng @@ -746,7 +746,7 @@ "Hasło (użytkownika/klucz prywatny):" "Pytaj o hasło przed połączeniem" "Pokaż hasło" -"Publiczny i prywatny plik klucza:" +"Publiczny i prywatny plik klucza (.ppk):" "Adres nie może być pusty" "Nieprawidłowy adres" "Nazwa sesji nie może być pusta" @@ -1265,7 +1265,7 @@ "http://filezilla-project.org/" "Ten produkt zawiera oprogramowanie utworzone przez OpenSSL Project do użytku w OpenSSL Toolkit %s." "Copyright © 1998-2024 The OpenSSL Project" -"3.2.1" +"3.3.1" "http://www.openssl.org/" "Kod WebDAV bazuje na bibliotece Neon %s" "Copyright © 1999-2016 Joe Orton" diff --git a/src/NetBox/NetBoxRus.lng b/src/NetBox/NetBoxRus.lng index ecc616157..791b3b3b3 100644 --- a/src/NetBox/NetBoxRus.lng +++ b/src/NetBox/NetBoxRus.lng @@ -746,7 +746,7 @@ "Пароль (пользователя/ключа):" "Спрашивать пароль при подключении" "Показать пароль" -"Файл публичного и приватного ключа:" +"Файл публичного и приватного ключа (.ppk):" "Не указан URL" "Некорректный URL" "Имя сессии не может быть пустым" @@ -981,7 +981,7 @@ "An operation was attempted on a file for which a delete operation is pending." "The file is corrupt; an filesystem integrity check should be run." "File «%s» does not contain private key in known format." -"**Private key file '%s' contains key in %s format. WinSCP supports only PuTTY format.**" +"**Private key file '%s' contains key in %s format. WinSCP supports only PuTTY (.ppk) format.**" "Private key file '%s' contains key in deprecated SSH-1 format." "Cannot overwrite remote file «%s».$$\n \nPress «Delete» to delete the file and create new one instead of overwriting it.$$" "&Delete" @@ -1265,7 +1265,7 @@ "http://filezilla-project.org/" "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit %s." "Copyright © 1998-2024 The OpenSSL Project" -"3.2.1" +"3.3.1" "http://www.openssl.org/" "WebDAV code based on neon library %s" "Copyright В© 1999-2016 Joe Orton" diff --git a/src/NetBox/NetBoxSpa.lng b/src/NetBox/NetBoxSpa.lng index 25ddadd72..04e2c07c4 100644 --- a/src/NetBox/NetBoxSpa.lng +++ b/src/NetBox/NetBoxSpa.lng @@ -746,7 +746,7 @@ "Contraseña (clave usuario/privada):" "Preguntar por contraseña tras conexión" "Mostrar contraseña" -"Archivo clave público y privado:" +"Archivo clave público y privado (.ppk):" "URL no puede estar vacía" "URL inválida" "El nombre de sesión no puede estar vacío" @@ -981,7 +981,7 @@ "An operation was attempted on a file for which a delete operation is pending." "The file is corrupt; an filesystem integrity check should be run." "File '%s' does not contain private key in known format." -"**Private key file '%s' contains key in %s format. WinSCP supports only PuTTY format.**" +"**Private key file '%s' contains key in %s format. WinSCP supports only PuTTY (.ppk) format.**" "Private key file '%s' contains key in deprecated SSH-1 format." "Cannot overwrite remote file '%s'.$$\n \nPress 'Delete' to delete the file and create new one instead of overwriting it.$$" "&Delete" @@ -1265,7 +1265,7 @@ "http://filezilla-project.org/" "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit %s." "Copyright © 1998-2024 The OpenSSL Project" -"3.2.1" +"3.3.1" "http://www.openssl.org/" "WebDAV code based on neon library %s" "Copyright В© 1999-2016 Joe Orton" diff --git a/src/NetBox/plugin_version.hpp b/src/NetBox/plugin_version.hpp index 294567778..54be5bfea 100644 --- a/src/NetBox/plugin_version.hpp +++ b/src/NetBox/plugin_version.hpp @@ -5,6 +5,6 @@ #pragma once #define NETBOX_VERSION_MAJOR 24 -#define NETBOX_VERSION_MINOR 5 +#define NETBOX_VERSION_MINOR 6 #define NETBOX_VERSION_PATCH 0 -#define NETBOX_VERSION_BUILD 602 +#define NETBOX_VERSION_BUILD 603 diff --git a/src/NetBox/resource.h b/src/NetBox/resource.h index 1eecde541..72965a4e1 100644 --- a/src/NetBox/resource.h +++ b/src/NetBox/resource.h @@ -26,5 +26,5 @@ #define PUTTY_VERSION_WTXT L"0.81" #define FILEZILLA_VERSION_WTXT L"2.2.32" #define ZLIB_VERSION_WTXT L"zlib-ng 2.1.6" -#define OPENSSL_VERSION_WTXT L"3.2.1" +#define OPENSSL_VERSION_WTXT L"3.3.1" #define WINSCP_VERSION_WTXT L"6.3.3" diff --git a/src/NetBox/resource.h.template b/src/NetBox/resource.h.template index d5883fb26..71e92ca95 100644 --- a/src/NetBox/resource.h.template +++ b/src/NetBox/resource.h.template @@ -12,5 +12,5 @@ #define PUTTY_VERSION_WTXT L"0.81" #define FILEZILLA_VERSION_WTXT L"2.2.32" #define ZLIB_VERSION_WTXT L"zlib-ng 2.1.6" -#define OPENSSL_VERSION_WTXT L"3.2.1" +#define OPENSSL_VERSION_WTXT L"3.3.1" #define WINSCP_VERSION_WTXT L"6.3.3" diff --git a/src/core/FileSystems.h b/src/core/FileSystems.h index 0327adc9b..bb56c824d 100644 --- a/src/core/FileSystems.h +++ b/src/core/FileSystems.h @@ -51,8 +51,8 @@ class NB_CORE_EXPORT TCustomFileSystem : public TObject, public TFileSystemIntf virtual bool GetActive() const = 0; virtual void CollectUsage() = 0; virtual void Idle() = 0; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) = 0; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) const = 0; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) = 0; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) const = 0; virtual void AnyCommand(const UnicodeString & ACommand, TCaptureOutputEvent && OutputEvent) = 0; virtual void ChangeDirectory(const UnicodeString & ADirectory) = 0; diff --git a/src/core/FtpFileSystem.cpp b/src/core/FtpFileSystem.cpp index 2de3d3ff8..7ebdee1a3 100644 --- a/src/core/FtpFileSystem.cpp +++ b/src/core/FtpFileSystem.cpp @@ -925,12 +925,12 @@ void TFTPFileSystem::Discard() } } -UnicodeString TFTPFileSystem::GetAbsolutePath(const UnicodeString & APath, bool Local) +UnicodeString TFTPFileSystem::AbsolutePath(const UnicodeString & APath, bool Local) { - return static_cast(this)->GetAbsolutePath(APath, Local); + return static_cast(this)->AbsolutePath(APath, Local); } -UnicodeString TFTPFileSystem::GetAbsolutePath(const UnicodeString & APath, bool /*Local*/) const +UnicodeString TFTPFileSystem::AbsolutePath(const UnicodeString & APath, bool /*Local*/) const { TODO("improve (handle .. etc.)"); if (base::UnixIsAbsolutePath(APath)) @@ -1049,7 +1049,7 @@ void TFTPFileSystem::DoChangeDirectory(const UnicodeString & Directory) { if (FWorkFromCwd == asOn) { - const UnicodeString ADirectory = base::UnixIncludeTrailingBackslash(GetAbsolutePath(Directory, false)); + const UnicodeString ADirectory = base::UnixIncludeTrailingBackslash(AbsolutePath(Directory, false)); UnicodeString Actual = base::UnixIncludeTrailingBackslash(GetActualCurrentDirectory()); while (!base::UnixSamePath(Actual, ADirectory)) @@ -1098,7 +1098,7 @@ void TFTPFileSystem::ChangeDirectory(const UnicodeString & ADirectory) { if (FTerminal->GetActive()) { - Directory = GetAbsolutePath(Directory, false); + Directory = AbsolutePath(Directory, false); } else { @@ -1136,7 +1136,7 @@ void TFTPFileSystem::ChangeFileProperties(const UnicodeString & AFileName, try__finally { - UnicodeString FileName = GetAbsolutePath(AFileName, false); + UnicodeString FileName = AbsolutePath(AFileName, false); if (AFile == nullptr) { @@ -1837,7 +1837,7 @@ void TFTPFileSystem::Source( void TFTPFileSystem::CreateDirectory(const UnicodeString & ADirName, bool /*Encrypt*/) { - const UnicodeString DirName = GetAbsolutePath(ADirName, false); + const UnicodeString DirName = AbsolutePath(ADirName, false); { // ignore file list @@ -1866,7 +1866,7 @@ void TFTPFileSystem::CreateLink(const UnicodeString & AFileName, void TFTPFileSystem::DeleteFile(const UnicodeString & AFileName, const TRemoteFile * AFile, int32_t Params, TRmSessionAction & Action) { - const UnicodeString FileName = GetAbsolutePath(AFileName, false); + const UnicodeString FileName = AbsolutePath(AFileName, false); const UnicodeString FileNameOnly = base::UnixExtractFileName(FileName); const UnicodeString FilePath = RemoteExtractFilePath(FileName); @@ -2162,7 +2162,7 @@ void TFTPFileSystem::DoReadDirectory(TRemoteFileList * AFileList) UnicodeString Directory; if (!EnsureLocationWhenWorkFromCwd(AFileList->Directory())) { - Directory = GetAbsolutePath(AFileList->Directory(), false); + Directory = AbsolutePath(AFileList->Directory(), false); } FBytesAvailable = -1; @@ -2246,7 +2246,7 @@ bool TFTPFileSystem::LookupUploadModificationTime( bool Result = false; if (ModificationFmt != mfFull) { - const UnicodeString AbsPath = GetAbsolutePath(AFileName, false); + const UnicodeString AbsPath = AbsolutePath(AFileName, false); const TUploadedTimes::const_iterator Iterator = FUploadedTimes.find(AbsPath); if (Iterator != FUploadedTimes.end()) { @@ -2482,7 +2482,7 @@ void TFTPFileSystem::ReadDirectory(TRemoteFileList * FileList) void TFTPFileSystem::DoReadFile(const UnicodeString & AFileName, TRemoteFile *& AFile) { - const UnicodeString FileName = GetAbsolutePath(AFileName, false); + const UnicodeString FileName = AbsolutePath(AFileName, false); UnicodeString FileNameOnly; UnicodeString FilePath; if (base::IsUnixRootPath(FileName)) @@ -2658,8 +2658,8 @@ void TFTPFileSystem::ReadSymlink(TRemoteFile * SymlinkFile, void TFTPFileSystem::RenameFile( const UnicodeString & AFileName, const TRemoteFile * /*AFile*/, const UnicodeString & ANewName, bool DebugUsedArg(Overwrite)) { - const UnicodeString FileName = GetAbsolutePath(AFileName, false); - const UnicodeString NewName = GetAbsolutePath(ANewName, false); + const UnicodeString FileName = AbsolutePath(AFileName, false); + const UnicodeString NewName = AbsolutePath(ANewName, false); const UnicodeString FileNameOnly = base::UnixExtractFileName(FileName); const UnicodeString FilePathOnly = RemoteExtractFilePath(FileName); @@ -4567,7 +4567,7 @@ bool TFTPFileSystem::HandleListData(const wchar_t * Path, else if (FFileList) { DebugAssert(FFileList != nullptr); - const UnicodeString AbsPath = GetAbsolutePath(FFileList->GetDirectory(), false); + const UnicodeString AbsPath = AbsolutePath(FFileList->GetDirectory(), false); DebugAssert(FFileList->GetDirectory().IsEmpty() || base::UnixSamePath(AbsPath, Path)); DebugUsedParam(Path); diff --git a/src/core/FtpFileSystem.h b/src/core/FtpFileSystem.h index b3608c684..437afcd27 100644 --- a/src/core/FtpFileSystem.h +++ b/src/core/FtpFileSystem.h @@ -35,7 +35,7 @@ class NB_CORE_EXPORT TFTPFileSystem final : public TCustomFileSystem virtual bool GetActive() const override; virtual void CollectUsage() override; virtual void Idle() override; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) override; virtual void AnyCommand(const UnicodeString & Command, TCaptureOutputEvent && OutputEvent) override; virtual void ChangeDirectory(const UnicodeString & ADirectory) override; @@ -103,7 +103,7 @@ class NB_CORE_EXPORT TFTPFileSystem final : public TCustomFileSystem virtual void UpdateFromMain(TCustomFileSystem * MainFileSystem) override; virtual void ClearCaches() override; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) const override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) const override; protected: // enum TOverwriteMode { omOverwrite, omResume, omComplete }; // moved to FileSystems.h diff --git a/src/core/S3FileSystem.cpp b/src/core/S3FileSystem.cpp index 51278d894..1ec18a365 100644 --- a/src/core/S3FileSystem.cpp +++ b/src/core/S3FileSystem.cpp @@ -954,7 +954,7 @@ void TS3FileSystem::Idle() // noop } -UnicodeString TS3FileSystem::GetAbsolutePath(const UnicodeString & Path, bool /*Local*/) const +UnicodeString TS3FileSystem::AbsolutePath(const UnicodeString & Path, bool /*Local*/) const { if (base::UnixIsAbsolutePath(Path)) { @@ -1073,7 +1073,7 @@ void TS3FileSystem::TryOpenDirectory(const UnicodeString & ADirectory) void TS3FileSystem::ChangeDirectory(const UnicodeString & ADirectory) { - const UnicodeString Path = GetAbsolutePath(ADirectory, false); + const UnicodeString Path = AbsolutePath(ADirectory, false); // to verify existence of directory try to open it TryOpenDirectory(Path); @@ -1248,7 +1248,7 @@ bool TS3FileSystem::IsGoogleCloud() const void TS3FileSystem::ReadDirectoryInternal( const UnicodeString & APath, TRemoteFileList * FileList, int32_t MaxKeys, const UnicodeString & AFileName) { - const UnicodeString Path = base::UnixExcludeTrailingBackslash(GetAbsolutePath(APath, false)); + const UnicodeString Path = base::UnixExcludeTrailingBackslash(AbsolutePath(APath, false)); int32_t AMaxKeys = (MaxKeys == -1) ? 1 : MaxKeys; if (base::IsUnixRootPath(Path)) { @@ -1389,7 +1389,7 @@ void TS3FileSystem::ReadFile(const UnicodeString & AFileName, void TS3FileSystem::DeleteFile(const UnicodeString & AFileName, const TRemoteFile * AFile, int32_t AParams, TRmSessionAction & Action) { - const UnicodeString FileName = GetAbsolutePath(AFileName, false); + const UnicodeString FileName = AbsolutePath(AFileName, false); const bool Dir = FTerminal->DeleteContentsIfDirectory(FileName, AFile, AParams, Action); @@ -1460,8 +1460,8 @@ void TS3FileSystem::CopyFile( throw Exception(LoadStr(DUPLICATE_FOLDER_NOT_SUPPORTED)); } - const UnicodeString FileName = GetAbsolutePath(AFileName, false); - const UnicodeString NewName = GetAbsolutePath(ANewName, false); + const UnicodeString FileName = AbsolutePath(AFileName, false); + const UnicodeString NewName = AbsolutePath(ANewName, false); UnicodeString SourceBucketName, SourceKey; ParsePath(FileName, SourceBucketName, SourceKey); @@ -1492,7 +1492,7 @@ void TS3FileSystem::CopyFile( void TS3FileSystem::CreateDirectory(const UnicodeString & ADirName, bool /*Encrypt*/) { const TOperationVisualizer Visualizer(FTerminal->GetUseBusyCursor()); - const UnicodeString DirName = base::UnixExcludeTrailingBackslash(GetAbsolutePath(ADirName, false)); + const UnicodeString DirName = base::UnixExcludeTrailingBackslash(AbsolutePath(ADirName, false)); UnicodeString BucketName, Key; ParsePath(DirName, BucketName, Key); @@ -1580,7 +1580,7 @@ static TRights::TRightLevel S3PermissionToRightLevel(S3Permission Permission) bool TS3FileSystem::ParsePathForPropertiesRequests( const UnicodeString & Path, const TRemoteFile * File, UnicodeString & BucketName, UnicodeString & Key) { - const UnicodeString FileName = GetAbsolutePath(Path, false); + const UnicodeString FileName = AbsolutePath(Path, false); ParsePath(FileName, BucketName, Key); @@ -2469,9 +2469,9 @@ void TS3FileSystem::ClearCaches() FHostNames.clear(); } -UnicodeString TS3FileSystem::GetAbsolutePath(const UnicodeString & APath, bool Local) +UnicodeString TS3FileSystem::AbsolutePath(const UnicodeString & APath, bool Local) { - return static_cast(this)->GetAbsolutePath(APath, Local); + return static_cast(this)->AbsolutePath(APath, Local); } void TS3FileSystem::InitSslSession(ssl_st * Ssl, ne_session * Session) diff --git a/src/core/S3FileSystem.h b/src/core/S3FileSystem.h index 7a14ef5c4..669aabb76 100644 --- a/src/core/S3FileSystem.h +++ b/src/core/S3FileSystem.h @@ -38,7 +38,7 @@ class NB_CORE_EXPORT TS3FileSystem final : public TCustomFileSystem static bool classof(const TObject * Obj) { return Obj->is(OBJECT_CLASS_TS3FileSystem); } virtual bool is(TObjectClassId Kind) const override { return (Kind == OBJECT_CLASS_TS3FileSystem) || TCustomFileSystem::is(Kind); } - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) const override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) const override; public: TS3FileSystem() = delete; explicit TS3FileSystem(TTerminal * ATerminal) noexcept; @@ -49,7 +49,7 @@ class NB_CORE_EXPORT TS3FileSystem final : public TCustomFileSystem virtual bool GetActive() const override; virtual void CollectUsage() override; virtual void Idle() override; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) override; virtual void AnyCommand(const UnicodeString & ACommand, TCaptureOutputEvent && OutputEvent) override; virtual void ChangeDirectory(const UnicodeString & ADirectory) override; diff --git a/src/core/ScpFileSystem.cpp b/src/core/ScpFileSystem.cpp index a38ae1ed7..2ac7f0eb9 100644 --- a/src/core/ScpFileSystem.cpp +++ b/src/core/ScpFileSystem.cpp @@ -452,12 +452,12 @@ void TSCPFileSystem::Idle() FSecureShell->Idle(); } -UnicodeString TSCPFileSystem::GetAbsolutePath(const UnicodeString & APath, bool Local) +UnicodeString TSCPFileSystem::AbsolutePath(const UnicodeString & APath, bool Local) { - return static_cast(this)->GetAbsolutePath(APath, Local); + return static_cast(this)->AbsolutePath(APath, Local); } -UnicodeString TSCPFileSystem::GetAbsolutePath(const UnicodeString & APath, bool /*Local*/) const +UnicodeString TSCPFileSystem::AbsolutePath(const UnicodeString & APath, bool /*Local*/) const { return base::AbsolutePath(GetCurrentDirectory(), APath); } @@ -1021,7 +1021,7 @@ void TSCPFileSystem::ChangeDirectory(const UnicodeString & ADirectory) if (FTerminal->Active && DebugAlwaysTrue(!FCachedDirectoryChange.IsEmpty())) { Params |= ecNoEnsureLocation; - Directory = base::AbsolutePath(FTerminal->GetAbsolutePath(FCachedDirectoryChange, true), Directory); + Directory = base::AbsolutePath(FTerminal->AbsolutePath(FCachedDirectoryChange, true), Directory); FTerminal->LogEvent( FORMAT(L"Cannot locate to cached directory, assuming that target absolute path is \"%s\".", Directory)); } @@ -2016,7 +2016,7 @@ void TSCPFileSystem::SCPSource(const UnicodeString & AFileName, } else { - const UnicodeString AbsoluteFileName = FTerminal->GetAbsolutePath(TargetDir + DestFileName, false); + const UnicodeString AbsoluteFileName = FTerminal->AbsolutePath(TargetDir + DestFileName, false); DebugAssert(CheckHandle(LocalFileHandle.Handle)); DebugAssert(LocalFileHandle.Handle); std::unique_ptr Stream(std::make_unique(static_cast(LocalFileHandle.Handle))); @@ -2755,7 +2755,7 @@ void TSCPFileSystem::SCPSink(const UnicodeString & TargetDir, else if (Ctrl == L'C') { TDownloadSessionAction Action(FTerminal->GetActionLog()); - Action.SetFileName(FTerminal->GetAbsolutePath(FullFileName, true)); + Action.SetFileName(FTerminal->AbsolutePath(FullFileName, true)); try { diff --git a/src/core/ScpFileSystem.h b/src/core/ScpFileSystem.h index 5a3942149..f8bc263a7 100644 --- a/src/core/ScpFileSystem.h +++ b/src/core/ScpFileSystem.h @@ -24,7 +24,7 @@ class NB_CORE_EXPORT TSCPFileSystem final : public TCustomFileSystem virtual bool GetActive() const override; virtual void CollectUsage() override; virtual void Idle() override; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) override; virtual void AnyCommand(const UnicodeString & ACommand, TCaptureOutputEvent && OutputEvent) override; virtual void ChangeDirectory(const UnicodeString & ADirectory) override; @@ -90,7 +90,7 @@ class NB_CORE_EXPORT TSCPFileSystem final : public TCustomFileSystem virtual void UpdateFromMain(TCustomFileSystem * MainFileSystem) override; virtual void ClearCaches() override; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) const override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) const override; void Init(void * /*TSecureShell * */) override; void FileTransferProgress(int64_t /*TransferSize*/, int64_t /*Bytes*/) override {} protected: diff --git a/src/core/SftpFileSystem.cpp b/src/core/SftpFileSystem.cpp index cda34a2ea..53b1a4c4e 100644 --- a/src/core/SftpFileSystem.cpp +++ b/src/core/SftpFileSystem.cpp @@ -3084,12 +3084,12 @@ UnicodeString TSFTPFileSystem::Canonify(const UnicodeString & APath) return Result; } -UnicodeString TSFTPFileSystem::GetAbsolutePath(const UnicodeString & APath, bool Local) const +UnicodeString TSFTPFileSystem::AbsolutePath(const UnicodeString & APath, bool Local) const { - return const_cast(this)->GetAbsolutePath(APath, Local); + return const_cast(this)->AbsolutePath(APath, Local); } -UnicodeString TSFTPFileSystem::GetAbsolutePath(const UnicodeString & APath, bool Local) +UnicodeString TSFTPFileSystem::AbsolutePath(const UnicodeString & APath, bool Local) { if (Local) { @@ -4353,7 +4353,7 @@ void TSFTPFileSystem::CalculateFilesChecksum( DebugAssert(Packet.GetType() == SSH_FXP_EXTENDED_REPLY); OperationProgress->SetFile(File->GetFileName()); - Action.SetFileName(FTerminal->GetAbsolutePath(File->GetFullFileName(), true)); + Action.SetFileName(FTerminal->AbsolutePath(File->GetFullFileName(), true)); // skip alg nb::used(Packet.GetAnsiString()); diff --git a/src/core/SftpFileSystem.h b/src/core/SftpFileSystem.h index 96e761c45..5b95a2b98 100644 --- a/src/core/SftpFileSystem.h +++ b/src/core/SftpFileSystem.h @@ -47,7 +47,7 @@ friend class TSFTPBusy; virtual bool GetActive() const override; virtual void CollectUsage() override; virtual void Idle() override; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) override; virtual void AnyCommand(const UnicodeString & ACommand, TCaptureOutputEvent && OutputEvent) override; virtual void ChangeDirectory(const UnicodeString & ADirectory) override; @@ -116,7 +116,7 @@ friend class TSFTPBusy; virtual void UpdateFromMain(TCustomFileSystem * MainFileSystem) override; virtual void ClearCaches() override; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) const override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) const override; protected: gsl::owner FSecureShell{nullptr}; TFileSystemInfo FFileSystemInfo{}; diff --git a/src/core/Terminal.cpp b/src/core/Terminal.cpp index 505902b99..b22a461a5 100644 --- a/src/core/Terminal.cpp +++ b/src/core/Terminal.cpp @@ -2380,9 +2380,9 @@ bool TTerminal::GetIsCapableProtected(TFSCapability Capability) const } } -UnicodeString TTerminal::GetAbsolutePath(const UnicodeString & APath, bool Local) const +UnicodeString TTerminal::AbsolutePath(const UnicodeString & APath, bool Local) const { - return FFileSystem->GetAbsolutePath(APath, Local); + return FFileSystem->AbsolutePath(APath, Local); } void TTerminal::ReactOnCommand(int32_t ACmd) @@ -3860,7 +3860,7 @@ TRemoteFileList * TTerminal::ReadDirectoryListing(const UnicodeString & ADirecto do { FileList = nullptr; - TLsSessionAction Action(GetActionLog(), GetAbsolutePath(ADirectory, true)); + TLsSessionAction Action(GetActionLog(), AbsolutePath(ADirectory, true)); try { @@ -3903,7 +3903,7 @@ TRemoteFile * TTerminal::ReadFileListing(const UnicodeString & APath) do { File = nullptr; - TStatSessionAction Action(GetActionLog(), GetAbsolutePath(APath, true)); + TStatSessionAction Action(GetActionLog(), AbsolutePath(APath, true)); try { // reset caches @@ -4468,7 +4468,7 @@ void TTerminal::DoDeleteFile( TRetryOperationLoop RetryLoop(this); do { - TRmSessionAction Action(GetActionLog(), GetAbsolutePath(AFileName, true)); + TRmSessionAction Action(GetActionLog(), AbsolutePath(AFileName, true)); try { DebugAssert(FileSystem != nullptr); @@ -4487,7 +4487,7 @@ void TTerminal::DoDeleteFile( while (RetryLoop.Retry()); // Forget if file was or was not encrypted and use user preferences, if we ever recreate it. - FEncryptedFileNames.erase(GetAbsolutePath(AFileName, true)); + FEncryptedFileNames.erase(AbsolutePath(AFileName, true)); ReactOnCommand(fsDeleteFile); } @@ -4719,7 +4719,7 @@ void TTerminal::DoChangeFileProperties(const UnicodeString & AFileName, TRetryOperationLoop RetryLoop(this); do { - TChmodSessionAction Action(GetActionLog(), GetAbsolutePath(AFileName, true)); + TChmodSessionAction Action(GetActionLog(), AbsolutePath(AFileName, true)); try { DebugAssert(FFileSystem); @@ -5026,8 +5026,8 @@ bool TTerminal::DoRenameOrCopyFile( bool Move, bool DontOverwrite, bool IsBatchOperation) { const TBatchOverwrite BatchOverwrite = (IsBatchOperation ? OperationProgress->BatchOverwrite : boNo); - const UnicodeString AbsoluteFileName = GetAbsolutePath(FileName, true); - const UnicodeString AbsoluteNewName = GetAbsolutePath(NewName, true); + const UnicodeString AbsoluteFileName = AbsolutePath(FileName, true); + const UnicodeString AbsoluteNewName = AbsolutePath(NewName, true); bool Result = true; bool ExistenceKnown = false; std::unique_ptr DuplicateFile; @@ -5345,7 +5345,7 @@ void TTerminal::DoCreateDirectory(const UnicodeString & ADirName, bool Encrypt) TRetryOperationLoop RetryLoop(this); do { - TMkdirSessionAction Action(GetActionLog(), GetAbsolutePath(ADirName, false)); + TMkdirSessionAction Action(GetActionLog(), AbsolutePath(ADirName, true)); try { DebugAssert(FFileSystem); @@ -7720,7 +7720,7 @@ void TTerminal::DoCopyToRemote( FFileSystem->TransferOnDirectory(ATargetDir, CopyParam, AParams); // Must be local resolving, as this is outside of robust loop - const UnicodeString TargetDir = GetAbsolutePath(ATargetDir, true); + const UnicodeString TargetDir = AbsolutePath(ATargetDir, true); const UnicodeString FullTargetDir = base::UnixIncludeTrailingBackslash(ATargetDir); int32_t Index = 0; while ((Index < AFilesToCopy->GetCount()) && !AOperationProgress->GetCancel()) @@ -8085,7 +8085,7 @@ void TTerminal::Source( FFileSystem->Source( Handle, ATargetDir, DestFileName, CopyParam, AParams, AOperationProgress, AFlags, Action, ChildError); - LogFileDone(AOperationProgress, GetAbsolutePath(ATargetDir + DestFileName, true), Action); + LogFileDone(AOperationProgress, AbsolutePath(ATargetDir + DestFileName, true), Action); AOperationProgress->Succeeded(); } @@ -8346,7 +8346,7 @@ void TTerminal::DoCopyToLocal( { try { - const UnicodeString AbsoluteFileName = GetAbsolutePath(FileName, true); + const UnicodeString AbsoluteFileName = this->AbsolutePath(FileName, true); SinkRobust(AbsoluteFileName, File, FullTargetDir, CopyParam, AParams, AOperationProgress, AFlags | tfFirstLevel); Success = true; } diff --git a/src/core/Terminal.h b/src/core/Terminal.h index 7d25af3a8..482ab333f 100644 --- a/src/core/Terminal.h +++ b/src/core/Terminal.h @@ -592,7 +592,7 @@ friend class TParallelOperation; void CloseOnCompletion( TOnceDoneOperation Operation = odoDisconnect, const UnicodeString & AMessage = "", const UnicodeString & TargetLocalPath = "", const UnicodeString & ADestLocalFileName = ""); - UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) const; + UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) const; void BeginTransaction(); void ReadCurrentDirectory(); void ReadDirectory(bool ReloadOnly, bool ForceCache = false); diff --git a/src/core/WebDAVFileSystem.cpp b/src/core/WebDAVFileSystem.cpp index 85649f28c..cf24ed319 100644 --- a/src/core/WebDAVFileSystem.cpp +++ b/src/core/WebDAVFileSystem.cpp @@ -95,7 +95,7 @@ static UnicodeString PathUnescape(const char * Path) } #define AbsolutePathToNeon(P) PathEscape(StrToNeon(P)).c_str() -#define PathToNeonStatic(THIS, P) AbsolutePathToNeon((THIS)->GetAbsolutePath(P, false)) +#define PathToNeonStatic(THIS, P) AbsolutePathToNeon((THIS)->AbsolutePath(P, false)) #define PathToNeon(P) PathToNeonStatic(this, P) @@ -587,12 +587,12 @@ void TWebDAVFileSystem::Idle() // noop } -UnicodeString TWebDAVFileSystem::GetAbsolutePath(const UnicodeString & APath, bool Local) +UnicodeString TWebDAVFileSystem::AbsolutePath(const UnicodeString & APath, bool Local) { - return static_cast(this)->GetAbsolutePath(APath, Local); + return static_cast(this)->AbsolutePath(APath, Local); } -UnicodeString TWebDAVFileSystem::GetAbsolutePath(const UnicodeString & APath, bool /*Local*/) const +UnicodeString TWebDAVFileSystem::AbsolutePath(const UnicodeString & APath, bool /*Local*/) const { bool AddTrailingBackslash; @@ -788,7 +788,7 @@ void TWebDAVFileSystem::AnnounceFileListOperation() void TWebDAVFileSystem::ChangeDirectory(const UnicodeString & ADirectory) { - const UnicodeString Path = GetAbsolutePath(ADirectory, false); + const UnicodeString Path = AbsolutePath(ADirectory, false); // to verify existence of directory try to open it TryOpenDirectory(Path); @@ -839,7 +839,7 @@ bool TWebDAVFileSystem::IsValidRedirect(int32_t NeonStatus, UnicodeString & APat if (Result) { // What PathToNeon does - const UnicodeString OriginalPath = GetAbsolutePath(APath, false); + const UnicodeString OriginalPath = AbsolutePath(APath, false); // Handle one-step redirect // (for more steps we would have to implement loop detection). // This is mainly to handle "folder" => "folder/" redirects of Apache/mod_dav. @@ -899,7 +899,7 @@ void TWebDAVFileSystem::NeonPropsResult( File->SetTerminal(Data.FileSystem->FTerminal); Data.FileSystem->ParsePropResultSet(File.get(), Path, Results); - const UnicodeString FileListPath = Data.FileSystem->GetAbsolutePath(Data.FileList->GetDirectory(), false); + const UnicodeString FileListPath = Data.FileSystem->AbsolutePath(Data.FileList->GetDirectory(), false); if (base::UnixSamePath(File->FullFileName, FileListPath)) { File->FileName = PARENTDIRECTORY; diff --git a/src/core/WebDAVFileSystem.h b/src/core/WebDAVFileSystem.h index 74c894857..76e6cc95c 100644 --- a/src/core/WebDAVFileSystem.h +++ b/src/core/WebDAVFileSystem.h @@ -29,7 +29,7 @@ class TWebDAVFileSystem final : public TCustomFileSystem virtual ~TWebDAVFileSystem() noexcept override; virtual void Init(void *) override; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) const override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) const override; virtual void FileTransferProgress(int64_t TransferSize, int64_t Bytes) override; virtual void Open() override; @@ -37,7 +37,7 @@ class TWebDAVFileSystem final : public TCustomFileSystem virtual bool GetActive() const override; virtual void CollectUsage() override; virtual void Idle() override; - virtual UnicodeString GetAbsolutePath(const UnicodeString & APath, bool Local) override; + virtual UnicodeString AbsolutePath(const UnicodeString & APath, bool Local) override; virtual void AnyCommand(const UnicodeString & ACommand, TCaptureOutputEvent && OutputEvent) override; virtual void ChangeDirectory(const UnicodeString & ADirectory) override;